Project Business Economic and Financial Data

Sales of DimSum Records, Asian-food restaurant in Medellin, Colombia

2024/2025

Authors: Daniel Gutierrez & Fabio Pimentel

# Required Packages--------------------
rm(list = ls())
library(readxl)
library(ggplot2)
library(GGally)
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(lubridate)

Attaching package: ‘lubridate’

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(corrplot)
corrplot 0.95 loaded
library(feasts)
Loading required package: fabletools
Registered S3 method overwritten by 'tsibble':
  method               from 
  as_tibble.grouped_df dplyr
library(tsibble)

Attaching package: ‘tsibble’

The following object is masked from ‘package:lubridate’:

    interval

The following object is masked from ‘package:zoo’:

    index

The following objects are masked from ‘package:base’:

    intersect, setdiff, union
library(forecast)
library(tidyr)

Attaching package: ‘tidyr’

The following object is masked from ‘package:reshape2’:

    smiths
library(ggthemes)
library(car)
Loading required package: carData

Attaching package: ‘car’

The following object is masked from ‘package:dplyr’:

    recode
library(DIMORA)
library(tseries)

    ‘tseries’ version: 0.10-58

    ‘tseries’ is a package for time series analysis and computational finance.

    See ‘library(help="tseries")’ for details.
library(lmtest)

Import Data

#setwd('/Users/fabiopimentel/Documents/Padua/clases/segundo año primer semestre/BEF data/proyecto/time_series_padova-main')

# target variable
sales <- read_excel("data/sales/sales_dimsum_31102024.xlsx")

sales[is.na(sales)] <- 0 # set to zero na values

Creating variables

#setwd('/Users/fabiopimentel/Documents/Padua/clases/segundo año primer semestre/BEF data/proyecto/time_series_padova-main')

# target variable
sales <- read_excel("data/sales/sales_dimsum_31102024.xlsx")

sales[is.na(sales)] <- 0 # set to zero na values
# economic variables
eco_growth <- read_excel("data/macroeconomic/economic_activity.xlsx")
fx <- read_excel("data/macroeconomic/fx.xlsx") #Foreign exchange is the conversion of one currency into another
inflation <- read_excel("data/macroeconomic/inflation.xlsx")
unemployment <- read_excel("data/macroeconomic/unemployment.xlsx")

Explore data structure

str(sales)
str(eco_growth)
```r
# other variables
google_trends <- read_excel(\data/other/google_trends_restaurantes.xlsx\)
rain <- read_excel(\data/other/rain_proxy.xlsx\)
temp <- read_excel(\data/other/temperature_data.xlsx\)
temp[is.na(temp)] <- 0
rain[is.na(rain)] <- 0
plot(temp$tavg) # no zeros in temp : OK

<!-- rnb-source-end -->


<!-- rnb-output-end -->

<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1wbG90LWJlZ2luIC0tPlxuXG48aW1nIHNyYz1cImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBaEFBQUFGR0NBWUFBQUE3UDZiK0FBQUVEbWxEUTFCclEwZERiMnh2Y2xOd1lXTmxSMlZ1WlhKcFkxSkhRZ0FBT0kyTlZWMW9IRlVVUHB1NXN5c2t6b1BVcHFhU0R2NDFsTFJzVXRHRTJ1aitaYk50M0N5VGJMUkJrTW5zM1oxcEpqUGovS1JwS1Q0VVFSREJxT0NUNFA5YndTY2hhcXZ0aXkyaXRGQ2lCSU1vK05ENlI2SFNGd25ydVRPenU1TzRhNzNMM1BubW5POSs1OTV6N3Q0TGtMZ3NXNWJlSlFJc0dxNHQ1ZFBpczhmbXhNUTZkTUY5MEExOTBDMHJqcFVxbFNZQkcrUEN2OXJ0N3lERzN0ZjJ0L2YvWit1dVVFY0JpTjJGMkt3NHlpTGlaUUQrRmNXeVhZQUVRZnZJQ2RkaStBbkVPMnljSU9JU3c3VUFWeGllRC9DeXo1bVJNb2hmUlN3b3Fveit4TnVJQitjajlsb0VCM1B3MjQ0OE5haXRLU0xMUmNrMnE1cE9JOU85Zy90L3RrWGRhOFRiZzArUHN6QjlGTjhEdVBhWEtuS1c0WWNRbjFYazNIU0lyeTVwczhVUS8yVzVhUW54SXdCZHU3eUZjZ3J4UHNSalZYdThIT2gwcWFvMzBjQXJwOVNaWnhEZmczaDF3VHpLeHU1RS9MVXhYNXdLZFg1U25Bem1EeDRBNE9JcUxiQjY5eU1lc0UxcEtvakxqVmRvTnNmeWlQaTQ1aFptQW4zdUxXZHBPdGZRT2FWbWlrRXM3b3ZqOGhGV3B6N0VWNm1lbDBMOVh5MjNGTVlsUFlaZW5BeDB5REIxL1BYNmRsZWRtUWppa2prWEN4cU1KUzlXdGZGQ3lIOVh0U2VrRUYrMmRIK1A0dHpJVGR1VHlnR2Z2NThhNVZDVEg1UHRYRDdFRlppTnlVREJoSG5zRlRCZ0UwU1FJQTlwZkZ0Z282Y0tHdWhvb2VpbGFLSDQxZURzMzhJcCtmNEF0MVJxL3NqcjZORXdRcWIvSS9EUXFzTHZhRlVqdkF4K2VXaXJkZEFKWm5BajFERkpMMG1TZy9nY0lwUGtNQmtob3lDU0o4bFRaSXhrMFRwS0RqWEhsaUp6WlBPNTBkUjVBU05TbnplTHZJdm9kMEhHL21ka21PQzB6OFZLbnpjUTJNL1l6MnZLbGRkdVhqcDlibGVMdTBaV243dldjK2wwSkdjYWFpMTB5TnJVblhMUC84SmY1OWV3WCtjM1dneitCMzREZit2YlZyYzE2elRNVmdwOXVtOWJ4RWZ6UFU1a1BxVXRWV3hoczZPaVdUVlcrZ0lmeXdCOXVYaTdDR2NHVy96azk4ay9rbXZKOTVJZkpuL2ozdVErNGM1em4zS2ZjZCtBeUYzZ0xuSmZjbDl4SDNPZlIyclVlZTgwYSs2dm83RUs1bW1YVWR5ZlFscllMVHdvWklVOXdzUENaRXRQNkJXR2hBbGhMM3AyTjZzVGpSZGR1d2JIc0c5a3EzMnNnQmVwYyt4dXJMUFc0VDlVUnBZR0ozeW00Kzh6QTA1dTQ0UWpTVDhaSW9WdHUzcUU3ZldtZG41TFBkcXZnY1p6OFd3OEJXSjhYM3cwUGhRL3duQ0RHZCtMdmxIczhkUnk2YkxMRHVLTWFaMjB0WnJxaXNQSjVPTmlDcTh5S2hZTTVjQ2dLT3U2NkxzYzBhWU90WmRvNVFDd2V6STR3bTlKL3YwWDIzbWxaWE9mQmpqOEp6djNXclk1RCtDc0E5RDdhTXMyZ0dmanZlOEFyRDZtZVBaU2VDZkVZdDhDT05XRHc4RlhUeHJQcXgvcjlWdDRiaVhlQU5oOHZWNy8rLzE2ZmZNRDFOOEF1S0QvQS84bGVBdkZZOWJMQUFBQU9HVllTV1pOVFFBcUFBQUFDQUFCaDJrQUJBQUFBQUVBQUFBYUFBQUFBQUFDb0FJQUJBQUFBQUVBQUFJUW9BTUFCQUFBQUFFQUFBRkdBQUFBQUc1RzBZVUFBRUFBU1VSQlZIZ0I3TjBIdUMxSlZUYmdSakZueklKaVFoMFQ1a1FZWkV5Z29pZ3FLZ2lLSWlZVVZGUVVaZ3dJSmtERmlESVlVRERnR0VpS0RJZ1JqSmdRaGFzb0pneVlzL3V2dDV6di9uWDc5Z243M0wzdk9mdWNWYy9UdTNkM1YxZFhyNnBhNjF1aHFtKzBhbW1xVkJRb0NoUUZpZ0pGZ2FKQVVXQU5DcnpjR25rcmExR2dLRkFVS0FvVUJZb0NSWUZPZ1FJUTFSR0tBa1dCb2tCUm9DaFFGRmliQWdVZzFpWlozVkFVS0FvVUJZb0NSWUdpUUFHSTZnTkZnYUpBVWFBb1VCUW9DcXhOZ1FJUWE1T3NiaWdLRkFXS0FrV0Jva0JSb0FCRTlZR2lRRkdnS0ZBVUtBb1VCZGFtUUFHSXRVbFdOeFFGaWdKRmdhSkFVYUFvVUFDaStrQlJvQ2hRRkNnS0ZBV0tBbXRUb0FERTJpU3JHNG9DUllHaVFGR2dLRkFVS0FCUmZhQW9VQlFvQ2hRRmlnSkZnYlVwVUFCaWJaTFZEVVdCb2tCUm9DaFFGQ2dLRklDb1BsQVVLQW9VQllvQ1JZR2l3Tm9VS0FDeE5zbnFocUpBVWFBb1VCUW9DaFFGQ2tCVUh5Z0tGQVdLQWtXQm9rQlJZRzBLRklCWW0yUjFRMUdnS0ZBVUtBb1VCWW9DQlNDcUR4UUZpZ0pGZ2FKQVVhQW9zRFlGQ2tDc1RiSzZvU2hRRkNnS0ZBV0tBa1dCQWhEVkI0b0NSWUdpUUZHZ0tGQVVXSnNDQlNEV0psbmRVQlFvQ2hRRmlnSkZnYUpBQVlqcUEwV0Jva0JSb0NoUUZDZ0tyRTJCQWhCcms2eHVLQW9VQllvQ1JZR2lRRkdnQUVUMWdhSkFVYUFvVUJRb0NoUUYxcVpBQVlpMVNWWTNGQVdLQWtXQm9rQlJvQ2hRQUtMNlFGR2dLRkFVS0FvVUJZb0NhMU9nQU1UYUpLc2JpZ0pGZ2FKQVVhQW9VQlFvQUZGOW9DaFFGQ2dLRkFXS0FrV0J0U2xRQUdKdGt0VU5SWUdpUUZHZ0tGQVVLQW9VZ0tnK1VCUW9DaFFGaWdKRmdhTEEyaFFvQUxFMnllcUdva0JSb0NoUUZDZ0tGQVVLUUZRZktBb1VCWW9DUllHaVFGRmdiUW9VZ0ZpYlpIVkRVYUFvVUJRb0NoUUZpZ0lGSUtvUEZBV0tBa1dCb2tCUm9DaXdOZ1VLUUt4TnNycWhLRkFVS0FvVUJZb0NSWUVDRU5VSGlnSkZnYUpBVWFBb1VCUlltd0lGSU5ZbVdkMVFGQ2dLRkFXS0FrV0Jva0FCaU9vRFJZR2lRRkdnS0ZBVUtBcXNUWUVDRUd1VHJHNG9DaFFGaWdKRmdhSkFVYUFBUlBXQm9rQlJvQ2hRRkNnS0ZBWFdwa0FCaUxWSlZqY1VCWW9DUllHaVFGR2dLRkFBb3ZwQVVhQW9VQlFvQ2hRRmlnSnJVNkFBeE5va3F4dUtBa1dCb2tCUm9DaFFGQ2dBVVgyZ0tGQVVLQW9VQllvQ1JZRzFLVkFBWW0yUzFRMUZnYUpBVWFBb1VCUW9DaFNBcUQ1UUZDZ0tGQVdLQWtXQm9zRGFGQ2dBc1RiSjZvYWlRRkdnS0ZBVUtBb1VCUXBBVkI4b0NoUUZpZ0pGZ2FKQVVXQnRDaFNBV0p0a2RVTlJvQ2hRRkNnS0ZBV0tBZ1VncWc4VUJZb0NSWUdpUUZHZ0tMQTJCUXBBckUyeXVxRW9VQlFvQ2hRRmlnSkZnUUlRMVFlS0FrV0Jva0JSb0NoUUZGaWJBZ1VnMWlaWjNWQVVLQW9VQllvQ1JZR2lRQUdJNmdORmdhSkFVYUFvVUJRb0NxeE5nUUlRYTVPc2JpZ0tGQVdLQWtXQm9rQlJvQUJFOVlHaVFGR2dLRkFVS0FvVUJkYW1RQUdJdFVsV054UUZpZ0pGZ2FKQVVhQW9VQUNpK2tCUm9DaFFGQ2dLRkFXS0FtdFRvQURFMmlTckc0b0NSWUdpUUZHZ0tGQVVLQUJSZmFBb1VCUW9DaFFGaWdKRmdiVXBVQUJpYlpMVkRVV0Jva0JSb0NoUUZDZ0tGSUNvUGxBVUtBb1VCWW9DUllHaXdOb1VLQUN4TnNucWhxSkFVYUFvVUJRb0NoUUZDa0JVSHlnS0ZBV0tBa1dCb2tCUllHMEtGSUJZbTJSMVExR2dLRkFVS0FvVUJZb0NCU0NxRHhRRmlnSkZnYUpBVWFBb3NEWUZDa0NzVGJLNm9TaFFGQ2dLRkFXS0FrV0JBaERWQjRvQ1JZR2lRRkdnS0ZBVVdKc0NCU0RXSmxuZFVCUW9DaFFGaWdKRmdhSkFBWWpxQTBXQm9rQlJvQ2hRRkNnS3JFMkJBaEJyazZ4dUtBb1VCWW9DUllHaVFGR2dBRVQxZ2FKQVVhQW9VQlFvQ2hRRjFxWkFBWWkxU1ZZM0ZBV0tBa1dCb2tCUm9DaFFBS0w2UUZHZ0tGQVVLQW9VQllvQ2ExT2dBTVRhSktzYmlnSkZnYUpBVWFBb1VCUW9BRkY5b0NoUUZDZ0tGQVdLQWtXQnRTbFFBR0p0a3RVTlJZR2lRRkdnS0ZBVUtBb1VnS2crVUJRb0NoUUZpZ0pGZ2FMQTJoUzQ4ZHAzMUEyZEF2L3hILzh4dmZTbEx5MXFGQVdLQWtXQm9rQlJZT01VZUpWWGVaWHBkVi8zZFRkZTdpWUx2TkdxcFUwV2VGYkt1c01kN2pBOTlhbFBuVzU2MDV1ZWxWZXU5eXdLRkFXS0FrV0J5MFNCbDd6a0pkT2YvdW1mVGplNzJjMHUweFBYZjB4WklHWTArNG1mK0lucG1tdXVtWjI5K1BCNXozdmU5SkNIUEdSNjRBTWZlUEhGT2xNVUtBcHNuUUwvOHovLzB4a3NIZWpOM3V6TnBwZC8rWmZmK2pQckFVV0J5MFdCVzk3eWx0UGYvdTNmRm9DNFhBVGZ4SE51ZmV0YlQ5LzkzZDk5WUZHM3V0V3RwdGQ2cmRjNk1GOWxLQW9VQlRaUGdaLzh5WitjN252ZiswNHY5M0l2TndFU2YvTTNmek05ODVuUG5ON2pQZDVqOHcrckVvc0NSWUZGQ3BRRllrYVdtOXprSnBQdG9FVGJlY1ZYZk1XRHN0WDFva0JSWU1NVWVNNXpualBkNlU1M21uNzJaMzkydXYzdGI5OUxaemw4ei9kOHorbkpUMzd5eEwxNG1QU0VKenhoZXVJVG45aGptVzV4aTF0TTk3dmYvYWEzZTd1M084eXRsYWNvVUJSb0ZLaFpHTlVOaWdKRmdaMmh3UC8rNy85T0gvTXhIelA5OEEvLzhIbndvUElBQmF2RUYzekJGMHdKNi9yalAvN2o2VWQvOUVkN3JOTExYdmF5Qzk3eDY3N3U2NlpQL3VSUDd2YzkrTUVQN3RiRUs2NjRZdnExWC91MUMvTFZRVkdnS0xBM0Jjb0NzVGR0NmtwUm9DaHd3aWp3ZDMvM2Q5Ty8vTXUvVEhlNXkxMHVxdG1IZmRpSFRYZTcyOTBtZWI3a1M3NWt1dTY2NjZiYjNPWTJFL0R3akdjOFkzcjJzNTg5Y1ZFKy92R1BueDd3Z0FkTVpsTEZpbmk3MjkxdXNuM3dCMy93OVB1Ly8vdlQ2Ny8rNjE5VWZwMG9DaFFGTHFSQVdTQXVwRWNkRlFXS0FzZElnWi83dVovclF2d04zL0FOcDdkKzY3ZWV2dlpydjdiSE9LUktYSWYvL2QvL2ZkN0trUFAyTEEvaUllNTk3M3RQajM3MG8zdUFKUXNFVjRkeWdRbEFndHZpY1k5NzNQVFRQLzNUMDVWWFhqbTl3UnU4d2ZUMmIvLzJQYi9qcHovOTZXT3g5YjhvVUJUWWd3SmxnZGlETUhXNktGQVV1THdVK09WZi91VXUwQi96bU1kTTMvLzkzOThqME4vbFhkNWw0bUw0KzcvLys4bTgrTmQrN2RlZTN2SXQzM0tTNTE3M3V0Y0ZGZnlxci9xcVBxMGFRUGpuZi83bjZaVmU2WlhPWHdjZXZ1ZDd2bWQ2NkVNZk92M1hmLzNYOU1JWHZyQ1greU0vOGlQVGJXOTcyK2t2L3VJdkpsSHZyL2Q2cjllQnh2a2IyeC9BQkFqNWhWLzRoZW1WWC9tVnB3Lzh3QStjM3UzZDNtM01VditMQW1lU0FtV0JPSlBOWGk5ZEZEaFpGUGlIZi9pSDZYM2Y5MzI3OWk4MmdRdEJRT08vLy91L1QrLzNmdTgzZmZNM2YzT3Y4STF1ZEtQcE83L3pPNmRQL2RSUG5iN2lLNzZpV3lNQWdrYzk2bEVkRUh6NWwzOTVqNDE0dFZkN3RZdGU4STUzdk9Oayt2VWJ2ZEViOWJ6UGYvN3pwNC8rNkkvdXozcm5kMzduRGhUVXc5ejdKREVYSC9xaEh6cDk0UmQrWVgvV1gvLzFYMC92L3U3dlh0TzNRNkRhbjJrS0ZJQTQwODFmTDE4VU9Ca1UrTlZmL2RVZW4zRFZWVmRkVktGditJWnY2QmFKWERCVjg4Lys3TSs2VmNCVTZ0ZDh6ZGZzd1pLLy91dS9QcjNWVzcxVmo0RkkzbkZ2cXFlODcvUk83OVJQbnp0M2Jydzh2Zi83djMrM1RnQVpTUi93QVIvUTNSNi84UnUvTVgzbFYzN2xwQzcvOUUvLzFDMFozL2lOMzVoc3RTOEtuRWtLbEF2alREWjd2WFJSNEdSUlFHQWs5OFNZeENuOHpNLzh6UFNYZi9tWEhUQndTN3o2cTc5NnoySUYyR2M5NjFuZEt1REVqVy84ZjZ5TXhlS3YvdXF2ZW96REozN2lKNDdGZGVEdzZaLys2WDE1NEkvNnFJL3EwejAvNGlNK29ydEV1RS8rN2QvK3JUL3Y2cXV2N3ZkWnhPZjY2Ni92NThlQzFBSGcrYmlQKzdqcGN6LzNjOGRMOWI4b2NLWW9VQmFJTTlYYzliSkZnWk5KQWJFT3YvUkx2OVJkRm1wSU1EL29RUS9xOFFtditxcXYyaGVNZW8zWGVJMGVGekcrQWVBUThBQTRLT1BoRDM5NG40MWhTcWMxSTc3OTI3Kzl1elZlNFJWZVlXSTE0SUpnWmZqelAvL3pQcHZES3BaZjltVmZOZ0VSMTE1NzdmbkZxRXdEbFZmY3d6eTk2N3UrNi9UaUY3OTRmcnFPaXdKbmlnSmxnVGhUelYwdld4UTRtUlFneE1VakNKUmtBZmltYi9xbVNmeUI5UjUrN01kK2JQckRQL3pEU1pDa2VJU2YvL21mUHc4YXZJMGd4OC80ak0rWWZ1aUhmbWdpMkFFRHlib1FqM2pFSTNxWllpSllHSDduZDM2bkx6ajFEdS93RHRPYnZNbWJUUC81bi84NUFSYVN0U0YrNEFkK29GczhITHN1SGtJOXJIZzVwai81a3ovcHNSVGp1ZnBmRkRockZDZ0FjZFphdk42M0tIQkNLY0JTd0UwaEVQSzkzdXU5dXZZUERQektyL3pLOUgzZjkzMTlmUWF4Q0JhTkFnemU5bTNmdHIvSmgzLzRoMDlQZXRLVCt2b1FyQldTVlNtNUdkNzBUZCswejh4Z1JXQ3BZT240K0kvLytPays5N2xQZDRGWUI0SkxRaUFtb0FDQWZOZDNmZGYwK1ovLytkTWpIL25JRGpxNFZqN3lJeit5eDBEYy9PWTM3K1diQ2NMQ1Vha29jSllwVUFEaUxMZCt2WHRSWUlzVUVLVElLcENaRHl3TVpsVHNsY3l3RVBmd1V6LzFVMzFSSjBJZGtQaUVUL2lFaWZ2Q1RBdEMyeWVPemREZ25uaWQxM21kRGg3R1JhRzRQb0FIWU1CNXJnbUptNEsxd3RvU1AvaURQemg5NjdkKzYrU1pyQmVTOVNBQUJQbFlRY3dLTVNYVXRFMUxaQU14ckNDc0l1LzkzdS9kTFJiOXh2b3BDcHhWQ3JRQlZla0lGR2hheTZwTkp6dkNuV2YzbHJiSXo2cVpqRmROMHp1N1JEZ2piOTQrU0xkcVd2K3FhZjJyOXAySlZlT3ZmZk8vQVlNOXFkQkF4NnE1RkZaTlFLOWFITVNxQ2ZWK1gxdGRjcVgvTkZmQ1NwNG0yRmNOU0t6YWVoQ3JGc3pZeTlPdld0Qmx6eTlmVzVueS9ITWJDRmcxc0xGcUlLQ2ZhMEJtOWJFZis3SDl2M28yUzBTdmExczdvcDlyd0dMVjFvem81VGJYeCtycnYvN3JWMjN0aDFWenNheWFwYVRYWmMrWHFBdEZnUTFRb0UwdFh2M21iLzdtQmtyYVhoRVhPdmJPS29xcTk5NHFCVnIzbmE2NTVwcHVTcVpKbW9kdnFlRktwNU1DUG14bGtTY3pJa3l6RkM5QXU1ZGU5S0lYZFF2QTBwc0xnbnlMdDNpTHlRd0piZ3ZXaUplKzlLVjlRU2pueFVlOCtadS9lYmNTM1BuT2QrNnJSNzdrSlMrWnJOM2d5NXhXci95Z0QvcWdYclIxSkJMYndFMWhOb2Nwbkk5OTdHTjdPUmFRWWxXUTFOUDZEcXdTbHJMbUJ0Rm5zL1lFOXdlWGh1OWt2TTNidkUxM3JjeGpJbnBCOVZNVU9HTVVLQUJ4eGhyOE9GN1hkRGQrYmNzSlk5Wk16dzk3Mk1NbTN5Nm9kUG9vOE5WZi9kV1RvRVVDWEZ0ekk1Z2RJWEVaQ0ZZRUt1Wko3QUh3WVBva29XL2RCZ0JFL3dFU25QdURQL2lEWG9aN3JSb0pZRHoxcVUvdE15MElkeUJEVEFRd0l2alM4VDN1Y1krKzZKUm5tcFlKaEhDRGlMZXdOTGJ5dVMwQUJOL0JFQXVoYlBFWC8vcXYvM3BCTlozL3gzLzh4d3ZPMVVGUjRLeFNvQURFV1czNXkvVGV2amZBWit3YkJUNlpMUEV6MC9CTWsrTmpyblM2S0dDbWczVWRMUGJFY2dBSUFBQ1dpd1lxV0FkZThJSVhYUFRTenQzc1pqZnJxMUVDSGVJWXpJUmdIYkE2cFNCSTM3S1FmQThEUUxEa3RTUmV3bExUQkw3WkYwbG1XYkI0V2IxU0FnN2tFV2ZCaXFCZmltY0FLb0RhNWg3cC9WTSthYlNVdWMrUzFyNmJVYWtvVUJTb3ozbFhIOWd5QlRCOEd1bVN5ZGVpUGhoeXBkTkZBWUtlaGc4Zyt2UzJHUXVmOW1tZk5wbXFDUmpRN0plK2RrbTdmKzV6bjl0blA2Q0lOUmhhTEVXM01MQktDS2praWdBZUFCR3VCVi9lQkRLNHh1S3lDRFhOcmdBUXJDQUp6Q1FCTkFJNkJXRHFsL2UvLy8zUHo2amdhZ0Y2bE1zNllUcXA0RWxBaEZYbDduZS9lMDNmRENGcmYrWXBVQmFJTTk4RnRrc0FBbVBPMlBORUh6dHkvVklUQm05RndWdmQ2bFpkVS8zdDMvN3RTeTJ5N3I4RUNoREF0UFgzZVovMzZSWURHanRBb1gxbzlxd1RscHllSis0TExnOXVMb24xeXRMUnZzb3Byc0pTMVQvKzR6L2VyUlJjSWZLWmpXRnhLQmFPMjkvKzloY1VDV2pNRTFEZytSSlFFa3VENHcvNWtBL3A5ZUlTa1lBUDB6NEJETk5CV1VGOGtLdFNVYUFvOEg4VU9GVUFncW1UWDdQU3lhSEFyVzk5NittNjY2NWJyTkNYZnVtWFh2VGx3OFdNKzV6OG1xLzVtdW16UHV1enVtYllJdVc3Y1BGaHBQamM5N20xTG0ySkFnSU84OGx0WDlFVXZFaWpmK1l6bjltZlNPajd6UFk4QVJpZjlFbWZOSDN4RjMveDlDbWY4aWs5b0JINC9LTS8rcU4rekhJQWVJaWg0QUl6dmRJOTFvOFFBR25KYXdJL0NjQVFGNUhBU2xNd2dZSWsvY1g5U2VJdHhvOXdzVDYwbVJyZEV2R0x2L2lML1F1Z2dFdWxva0JSNEFZS3RJRzRjNmxGYUsvYWluU3JGc3pVNjk2MGsxWHpxL2ZwVjAzRDZOT3RXc0RlVnQrcnBuRWVqcnltN0RVbTNkdkdkRGpKVk03MlFhUityZ21hd3hXMGtPdDd2L2Q3ZXhuS0cxTnppL1FwZTAyZ2pLZnIvMldpUVB2WVZHK1h4bUpXemJYUXAyWDYzNFJ6UDIvYVpmdWE1bUp0bWtYcS9OVE41c0pZdFVXZit0VE1abDFZdFFXZGVua1BlTUFEZXBtdU5VQ3hNdVhTTldQZmM4Wk5QMnRmMGx6ZDVDWTM2Zm5HZXJUMUgzb2RIdktRaC9SckRheXNHdGpwOTdlUGFLM3VldGU3OXYvTjNWSlRqeGRicTA1dWt3SzdNSTBUa3QrcDFCYUY2WU85bVJzN2dHaWFabWNjNW1nM3pXVFZ0SWJWYlc5NzJ6NEhmWnNnb2dERTRidE4wL3BXelJMUjUvQWJGSmgwVzlsdjFjemNoeTlrSVdjemVhK2E1cmx3WmJWcXZ2ZFZDN0M3NEZwYk9HalZsakR1UXFpdFlyZ2lPQ3B0bmdMYW1xQnVadjgrTnJWNW14clp6N1V2WWZieDZ4Z0FpQkl3MXVLQkQzeGdYK01CTUdneENqMi9OUit1dU9LS3ZsNERJT0k0UUtITm5saTk0enUrNC9uam5NOCthenRrRDhpMktaODlmNXNxdWdKYWNweDc3RDAveHkwUWM5VmNNYjN2Tmd2S3FuMUtmS3h5L1M4S2JKd0N1d0FnZG00bFNxWkswLy80UkNYUjFhS3N6UnNYdkNWOXp1ZDh6dVF6dkk5dGM3NXZjNXZiOUhQMWMzd1U0R2ZtUi9ZWlppWmtKbWptNTBzMUIvTmh2L0Vidi9IaWl3bXNjejJKNy9velAvTXplNlQrTFc5NXkvNXRCU3NWV2lYeDhZOS9mTElkZXM4MGJ3WUo4N3JBdTN6VjhkQUZuTktNMW1Yd3JRcWZ6T1pDRURCcFNxWFVHT0tFYm8zVDlrOW4vOTd2L1Y1M2I3aEhleVdaamFIdHJNUFFGSVB1K3VEdWNzNG50MzJmQXQyVEJGczJwYUZQMmZTOUM0a3JRcXlEMlJXQ09TVjhRbC8wWEhXeUZMWXZkajc0d1EvdW4ranVtZHFQdW91anlTd041N2xIYko3TkhhTVBtZmE1bDNzdVpkVytLSENhS2JCek1SQ21kZ2wyU25yWnkxN1dtWGZBUTg1Yi9yYXQ0cFhEMmg4VEJmakNyN3p5eXY2RlJJRjBGdW14V0kvSStFdE5CQUJodFpRc29jelhMb21IdU9jOTc5bm43MXRLbVhEaEt5ZE1BRS9UVE5kSmZQSHVmOHBUbnRJaitYLzNkMyszKythdGM3R0xpVUFuVUcxalVPRlIzc1U2Q3RvYktMQVV0TVdkQ0dKVEpjVWltQTJCL2dSK2dpV3QwNkFPa3VCTGl6d0JDcC85MlovZGxRTGc0WGEzdTEybnRmRVBGQ1JadytGdWQ3dGJ2ODg2RVpKWUJ0K3ZBRmdDSGt3ZEZ0UUp3QUFjMmc2UUVGVDV3aGUrOEh6c2hKbEJ3SU8xSlBSVmExTklabXhjZGRWVi9RdWh5a1VuMDFWOWZLdFNVZURNVW1EamRwY3RGOGh2MlpqSkt2NzBGb0c5YW5QSFY2TXZ2UTN1MVYzdWNwZFYweTYyVnB0eVlSeU90STNaZC9QMW1MdEZ6SGZUOEtVdUJkNFllQytuQmVTTnhhL2FkTDkrUGtzbU16Y3ppeThsYm8wMnhYRHAwdUs1K1BkYm9PQUYxMXVRWFg5bUUzQVhuRC9wQjIxaHBSVlRhWnRDMldNUGJuclRtNjdhQjZ1T1hHM3hTVTA3WHpVQTMrTVMyamNsTG5JUHREVVl6cGQvaHp2Y29ic3BNcDdiV2c3OWZqRUx6V3JWM1V4Y0lkd1d6WUxVYWR3c0FLc211UHQvYmdteEM1YXBia3k4TDV1dC9adEMwZDJZWWlPY3o4WWw0bit6VHF6YUlsVGRKV0pwYW1Wd1dUU0x3cXBacG5yOVB1L3pQbTkxeHp2ZWNjWHQ0cjZuUGUxcFBkWXFsVy9nWXRYQVR3NXJYeFRZS0FXTXkxckt1bzNXVGFZditxSXY2aG9DallicG1VWkowNlQxbUROTzgvVGxQSXZKM085Kzk5dmtvNnVzTlNsQSsyUHliVUwzZ2p0RjVkUFdzMVR3QlJmWE9QQkpadHFpT2YxTkVQWFpHRXplYlJSMzgzV3NVa3padE42bFpLMkFUT3RidWo0L3AxLzUwcU1JL2pIUnR0dTNFNmJ2K0k3dkdFK2Y2UDgra1UzVHR3cWpGUjFaSUx3WDEwNFRsa2VxTysxY1dhWlVXdi9CQ3FSbTR0RDBKZFlubitST3NxQVRiVDRmdkdLQmFPQ2hMelQxOEljL3ZLOEpvUTlwVjNsWnNWZ0RUQlZWcG1uQXJJMnNBOHBsYVRBVjFBZXpXQWRZS0xVeEN3WVhSZ3VvN0kvV0gwek4xRWRhVUdhL0pwL1pIMWFzTkxOSHZ6Q3JpOHRDSGZXM3NhOVllNkptZmFVbGEzOFdLYkJ6TVJBWUJPRmpTaGJUNVRndHkwcDBFZ1lvUm9LcHN0TGxvNERGZHBoMStZcE5uOFA0QVRzbTdIbmlRMzd4aTE4OFA3MzJjUXVlNnlzZFdxS1k0TEtXQU1IMTdHYy91L3ZYUFlmQXQxWkFzMEpjVkQ2QlNXZ2NOaEV1NG11V2t2Nm1IcnVTbXBXdXgzRVF2UHo1cGtHTFV3R1Ntdlk5Y2Mwc3RkMSs3MmR4SitzM2FCZEMzVE1rNDVScklkK2ZTQm0rZHdFdzZDc1MxNUJQZG91UEFUemJCN1g2YXBPK3dzbmRKR2JsK2M5L2ZuZVBjRk1BQ0phM0JrQW9FOXhWNHA3MEFZb0VGNWRuV3N4TW5FV2JXZEZkV1U5NHdoTTZNQUQ4Z0FsZ3dNcVdTVmJOZE93OXVHT3NSUUh3V3N3cVNTeVBhWjZWaWdKbmxRSTdCeUEwbElWcGFCY0d0S1ZuRFhBTHlXQVF0QXErOGFNbWk5VXN6VkdmbDBmem9abFUrajhLOEczVExna2NLdzd5TVZ1V2VLOUFTVUZ3WStEY3BkQ1JWa3BRMFJLQkFRS1F2MXUvK0szZitxM3U2N2JVTVExVFA0azJqUGtUU1BlKzk3MFAvWGgxSnVDV0V2OS9jd0VzWFRweDUyajYyZ0JnQUxLc3Q2RGRudlNrSjNWaGlVNEFtUmlHZFpQWUF2MEFtTkwrQWZuS05GNnppQlJoYjkwSHdqbDBzeHJsZmU1em4yNXA4UHptZnByYWROME9ESlVES0xUWkdCMW9pSEhTbHZtdWhyVWFXQ2VBUi9FVnZvUEIraEZGZ2hWQ3ZJVytJQlpDc0tRK1lYWExNYmt2WUFJZ2x0REttaU4zdXRPZCtyRjZpOGZJMmhiOVpQMFVCYzRhQlRicXRMbk1oWWwxMkN1WkltaGJOeldCMC8ydXB2anR0N1dBclZVems2NWIvS25NMzRJS3UxLzVRUTk2MFBuMzB6YjgwS1pzbXE0M3BpWUlldjVtaGw2SmtXakNmaVdXNVZLVHRRTGErRjAxNFhHK0tIRVd6dkVsZWxZVE9EMkdwZ0dCVlJPWTNkL3V2SFZGeERFY2xKcVd2aktsenhvVVkycGdwVC9IR2hTN2tKcnB2Y2NJb00wMTExeHp2c3JhclFuL0hoUFFabENjUDMvWVAwMTRkenBvaTZRMmU2S2Y4eXhiRTlwOWlxZjFGVXpuZFc0K1ZwdkZvWDg2dTFrSWV2N2NheXFuZnBWajdXbEtidHJaK2VhVzZkZkZOQ1R2SXg3eGlGNGQ3eVNQbUlva2ZjRTVuL1YyVDhyT1hqeUc1K1JZL2RYTGUxVXFDbXlMQXJzUUE4RmZ2SE9wVGNucndvQVFKM3lhbWZLaWQ4Q1lyQVd3cllTSlhHb1E0TGJxZHJuTGJWSHlxNmFaTFQ1V0FCckdLekROdWd3QzFnVHNPZGRtUDZ5YTlyaDYxck9lMVk4dkplaTFtYkY3R2ZORnBRVGNOVXREZjc0NS93Q2k1NmtYQUdNZGtYUG56cTBFVTZwVE0zY3Z2c2Q0c2xrYWV0NjJ0UEdxbWNJN2tCVE0xNllOajlsTy9QODJCYll2dWphdnFPQkFRWVZIQVVQTm10Q0Rtc2N5ditWYnZxWFRLd0s0eGF6MFkyQ0F3QWJLeGlRZzJyTmIvTVJLc0NvYXV4ZmdTMzl5bi90ekxXVm5Md0F5Nno0NEo3QlRhbE84Vitxb0RsTDZqYjZwL0cvN3RtOWJ0ZVd5TzM4QkZLMDNJUytBbzYrMlphNVh6Uld6YXU2M2ZuLzlGQVcyUllGZEFCQVhPNmZiYUR2SmlibVJHVklzaElBb1prNVR3aDcxcUVlZDVHcWY2cm94NVRJN0x5VlRiazNaRks4aUNPN3BUMzk2ajFsb1FydTdIWmpOdFIvek5IT3c3MW9jSlRGbiszQVRVM3dTMDdhZ1ByNTkvNXR3Nk9aNmRSQjgrYUlYdmFpN09wb0ZZbXF6ZTNvY0FMZUdZTUw5a3FCZEFhTFdvR0RxNXI1UnBuNjVTNG1MaWN0T1BFQmpncjNxMWxscHEwVDI5UkgyY3RYczk0N29JdEE1U2ZrQ0V0SFVtQldmNEVOYXBsK0tnUkg0bkE5cmNVR0pleEE3WWQwUW44M21KcFNYRzhPM0tMU2I1Q3VaWWpTNExRUkhaZ3FuYTF4YTFwK3cxb2owNkVjL3V0OG5Sa3A3Y1VjazJGVy80ZkxrNm1vekxuby90SVMxTmxWWE1SWmNtalo5bFp0T0FMZG43MUl5dmdSOHBwMTNxZTVWMXhOTWdXMmhwMjJWU3h0b2cvaDg4VXl1VE9lTnhCZG9nR1dCT0UraXJmOWg2ZGxyUlVoTEZ0TkFrMXJjeXFyRkhPVHdnajNMa3VsL1IwbW1CbHFkTk1reTF2cEUreGpUeXRUQXh2VDdKVk02bWJWTkExeEtWcmVrMVo2RlpDdzE0TjJ0RU0zdjM4MzZWblMxZ211TEplbmErTHAwc01Ja2kxUlNtNW5TclFpT2FmUGpFdGI2UmZvQ3F3ZkxRRndJeG0rc1NXMmRodDZXcG5Dem1uQTFXTzFTMjVwMmFncG9BMjg5RDZ1QmRzODBXKzlpR3FoejJwMzFZTFFjNmpjTktQVHJySmxXcE9UQ2FVSEFxN1pnWFQvZjRtVDZQdE9GTFkvTlZiTXJ5VlJhYmhqTGlwdnVhclhlU2llZkFydGdnZGc1RjRiQlN3ak5rM24reks3TlF0RXZGWUNZVTJoN3h4aHlpM3EvNkhzQlRMNFlOek54a3JpU3BqM204SUo5QzM3c1RQdUNrNGM4RUllQlFYSkpTQzNnYmRWV2grei8xV0VVYWdSWmkrN3YxK1kvOTdyWHZWYUUyVmxJM0VtK0pRR0VpNG13K2Q4c003M2QyalRQdGNrZy9rQjhRZFoxME5adEJzU3FUY25zWldaOEtoam9GQi9UckFIOVdwdUMzUUdFNWEyQkNlM1dnaDE3SFFodkxpY0FBcEJ3VFZ5Qy83NnRZZXc3Wi9OZStvSTY2SHRBaVhnTDRBaXdzSng1VXZxTi9wTDcyN1RXVmJPVzlPTm1QZW5MVm5OdkFDNVpZNlJONTB3UkozcmZMSC85UGJTcHhGM2tQYm1DeHJWelR2UkxuTkhLRllEWVFzUHp0ZC81em5kZUxQbnVkNzk3MXpENHVRdEFyRHFESU1RSjFhTUV4QzBTZVkrVEZnVENtSHlycEUyQjZ3dnlPR1pWR0ZPTDhqOXZEUmpQKzAvZ1k5NUhUZnpUbnRsY0pxdTI2bUVYRnZvS29TTndrMFlyZm9FL3ZFMFh2T2d4aEtmN2QyMHhxSXRlWkhiQ3R4NmF5WDFsa2FjMkUrTDhWZTlMOE5MbXhSRTFOMHpYNnRHZ3VaTE81MXZuVHpQNWR4cW03VmtnME4reEdCZDFTUUkyQUR2WG1zdGd4UnJRVm9Ec2VXajl6UVZ4SHVqcHY3Um84VE9VQlRFMTdzTVBXQlpjYzV5TnBZR2k0UmpRb0hrcno3R2dTM3Z0ck56MjljOStMUERUZHk0c1dKWHlVeDdRTVFaU2prQW83M1BTOWdsb3pZSnFZLzNhMU9ZTExMYmp0ZnAvTWloUUFHSUw3ZEFXaitvTWd5bTArVmN2ZUlLQlFnaFpmWTVtZFphREtBbUs1a3Z1cXd1MitmRmRDOU1odDZsMXNDNWd2QVFHb2RTV0pMNmdmUndRNGt6Rkl0L0haQ1lBWnQxaVdzYlRhLzBYTU9uNWd1ZVlvWlhubldtaVZxMWtKYUhaSm9qVEZ4ZVRBQXptYjZicjA1VE1QcUU5ZTI5Q0EwM0cyVExlbFJXQUVMYXhIc2dUYy8xUmFBRWsrQUxyR01Tb2JMUlZkcHZtMllHQi93Qm1MRVhQZmU1eis3alZOM3k0S29LZXF3TXdCZnJhbE14ZUJsZUorK2ViZHZlc25PZWFHZlBpRzRCQVc3SzZhK0ZjSUcxNjU4b3NEZVBFdlo3ZEZxRTd2NEltQzBiSzFFY0VienQzS1N0MkhvV3U2OTRqQ0hXdkZWaXZ2ZmJhRllXcjBzbWxRQUdJTGJVTlB6Ym1aSkRQa3lsODk3em5QVHNEMlJVQXdVSkFPNklsbWZhSWdaa1ZjTlNFQmhpb1pYaHBtUkp3NVJ4Lzc1SkdjdFJuSGVVK0FvYUd5Q1FzNW9CcG1iQzRsTWgySm1Ydmx4Z0s0REtDb3dWcDltdG9hbnFnZktadTJuTm5zRllCUGF3VngwMmJvOUJ6cjN0YVFHTi94M0YyQ0kzYmU4ZWxRMmc3QmlyMEYyMEJlRG8zM3BkbnRFRFhUaS81eEFqTXYzaWFmUFptdlNoSEhJSTk0UjZBd2gwaFRvWGJ3ckx6RXN1aGZNenVralprRVhET3hoWFNGb2c3Znh5TFFPSW1nRkR1RDNsenptd3A4Uy9PNTkyQkc3eURld1Zvc1BuUGNxWS9BRncyNWFnenV2alBza1V4RVNkQlNVbWNSYS9zQ2Z3UisyQmJTaXhNR1N0TDErdmM4Vk9nQU1RVzI0QldhY0R2bFdnc3BtTnRLMjFxR21mTWpCZ1Voa1FUOHQ5MjFHbU5OTGE5TkdtV2dSYUp2aTJ5N0ZzdU0vcGpIdk9ZN3Z0dUt3K3VXa1I5cndzQU5hN2RzRzhoZTF6a3c2YWRqb2tXalk2MFVQUDJBeHJhMXhlNytkbzNNRnduVEh3SzNsb1VqM3prSS9zYUR3TDNkajBCWjIyWjVvdGVnNldHQUd3ekk3bzdSeUFqTUtkZjBLb1RyMENZam9ES0ZGZjBFck5BdUxNd09WNkthV0VCY3kyZ1FNd0pvWlVnVmdMZTFFaWcwWE44WTRRbElBSFI2aTdlZ0N0S0VDUlhDL2NJa0gzOTlkZjM5bU81OEF4QXdqb2U4Z0dCenJVdnBIWkxnZnhpTzVLczNhQS95QU9vY04zWUFDTG5FdVBnZjdhNFJ3S284djJPK2ZvbWVjWkoyYmNWUVh2N1Jva1k2d1V3WDRxU01wWlYvN2REZ1ZNQklNeVo1LzliMnRveXI5MHNDcUdQa2ZiYkllZkpLblVUQUNLTEQyRlU0NXg3VEJ1RDk0dzJCVzN0RjhjWXcrem1OL05KdCttdjg5TmJQY2JBMnNwOTNXMGhXbDcwdjNlbWZXNHFzU0lzdVV6MFg4S0haY2N6NTlIenRFbkNURjltbXBZbmF3MjByMEZ1cW5ySFVnNVhBS0MybEZnWmFQTUpQcHdET0s0UGRBbTlCRlNpamRpRU1RRUJhRHNIcFVDaGdHZW0vemtkQVFGQ1B3dXhBVG5LQm1JSWU1YUp1RnZFT0FpSzVMNFFJMEh3SlJrelhGWUJFS3dGc1VJb3kvc0Qwb0Jya3I2b25RR0xNWmwxd2pxUzJJZUFqRmd5bEdGTWlpTVJwNE51bDNzY2pmVTk3UC9NSkVuc1M5eEw2RDJDdzhPV1Yva3VId1ZPQllCb2M2YlByK3gyaTF2Y29pL0VZakVXWm5hRGl4bE00SlBCYS9HV3M1STJBU0JvWkRTZXBVV1l4SG93dmFMdHVvbEdhVUdjcFlUNTdXWFdYTXEvaVhNV2Nwb3pyQWdraTBsZFNnS1VDSHo5RDRNWE9EZlh1R2lRZk5jUmhubGVvdjhKR3ZVVGtTL3EzMy9tYW52V2lua2lOUG5TQ1ROdUVtMG9PUFNrSmViMjl0Mkl4V3FKUXhFMFNmaWl3MUxpSm56WXd4N1dMNW51YWVHc3BXUVdEcmZobUZnb3VLVkdnWi9yZ0xOWkVlTzEwSnVWaUVVQ1RlVkxVaFl3cUMzVHZrQVA0QWVreE0xZzlrVmNWZ0NCL0tNMUtWWVRiUTVrc0ZwUWZ0U0g5VVdiYy9PSkhVQS9aUU1MOGdNTUNiaVVUeXpIU1U5b3haV3J2c0FVc01kS3N5dXpTRTQ2ZmJkWnYxTUJJTTYxVmZvd3lUbWpGM1IyNVpWWDlvaGxSQlFCajRuVExzNUMyZ1NBWUM0WCtTM3FlNTZZYVpsVm1lV1oxNEV6ODk1RnF4K1VyR09BV1lUUkpqL0JoNUVzcmR5WlBKdmVaNW5yMFl5Y1o0d3pNbWhJckMzY0NZVEpZUUxVTUg3dlF6UGw3Z0VnSFB1OGU5WVFpRStjUm1rR2htY3dsZE9PWTNIUXYxbG1rZ1QyRVQ2ME44S0RCbzJtQWxCcGJRUXJQenJ6T3lIR1ZlYTUzRE1uSVdsblMyMFRyb0ErYThDWXhER29MNW9UMWl4Q0krMVpIOXJINmpvTjdDVnRzZ1NtWEdQSlNDQ2tZNG1Ma2ZBbStPZUpHNDFRMHliNnFCa05CRE1GQlhBQWNOSGMrT0NtOUM3cXl3M0NOVEZPd2NXZlhOTk8ydDIxV0E4RXpicEdZQ3JMbE0rME9mTStiVHhBbGpLa0QrQmg3UU5yM1UxeTh6YVYwN0V5OUFlQXgzTWNHNU83bEl5L0Y3emdCVDBXWk00WGR1azl6bEpkVHdXQXdGZ3dvYVYwM1hYWDlRR2RhOHpCQnVaWlNKc0FFQmduQnJzMHBaQ1Z4elhDQ3NEQUFBV2JZVjZzUWdjbFZnMTVDUXR6NFpsZUhZL005NkF5am5JZGM2TEZleWFtNWZzU2d0U1drdXZvU0pEUlBBa1YvbmV4SU9xNjErSlV5Z3JqcDJGajlHZ2pNTTk5TmhZQ2d0Ti9jL250Q1FNYUpUTTE0WnE4OXRIVXJRTVJ6VE5CbUFRU2NFTEk4UGNUVlBOa25yMTNFYWgzbkluZzVtNFVFeEN0M3Z1eFBORTZXYlljeHhyRHRlU1lodTNkOURYSE51K1pPQ0x4Sk9QM0xjWjNGTTBQQU13VC9xQWNyZ3FLaFprdzBZWXBKQUF5NnhRTGtoazhMQnp5YXlNekNMeEQ2Z0x3S1NkclFKaUtLNWFERWdONHlLZjkyeXFZZlFaSnBoWHJHd0VrTWVjRE52clBtTFF4MEExZ0pQWUlhTS96bGExZStrQmJkWFc4OWNUL0IzeTVoVmhpNXE2cUUxLzVNMXpCVXdFZ01BR00wV0NkSndQVEFKVjBVcEgxb3JyUFF0b0VnS0ROOHZWaVhxYlpKWVhKWTE0QTNKaE12eklOOFNCTGhIYVFqNGxhT1JnZlArODJrMEE0d0VVL0FINDgwM1E1bXVCU0luUk5vMU8vK1pTeWFKWjdBVkowd2VqZEt4Z3lpUUNoVlRzUDBOSWFtYWVqU2RJZzQzWUF6dVN6QVJzUnVMUmM1d2dNZSsraHJ3TWRDZUxMODhZOVRmNDRWN0hVbjlTWFlFNGlNQVFrT2s4NHNweGtEUVBYbk04MWUzUmlJY2g1V3JvRW1CRDAzQU5qaWhWb3IvNW9rU2Rsb3FITnVBbGR4YTFna3F5WllndzhNM0VaTkg3dEZJdUJnTStrekM3aGduQVBOMS83SEhtM0xPbnZucE5yM0lEYVUxbjZJVkNTUmFPeVNKVnlnUUpsZVQ5dERIU3lZam5ITGFKTS80R3NYZExnMFVwL01DYndHSDBlU0s5MDhpbHdLZ0FFb1dEd0dYakFoR05tNFNjKzhZbmRSSG5mKzk2M0R6UStRd0lMTXpnTGFSTUFBcDB3Wm96SlJyZ1JxSmltZ1o3cGJYTjYwcTZaV2ZkS1dRRVMyRWhpQ2ZDTThWeXVaVThybzNXWlVrb3pOQTN2c0ltZ1ViNWx4aU4wRWs5QWUyZmlKc2lVVFZ2TkZ4cHBoVXRtYnMvbEVpQmtscExsZUFsMGROSS9BOEw0N0ovMnRLZDFZYUUrWWlJSUh3S0FKYzA1R3JwZ1R2ZnBzd1FhSUp4WUNIbFlJV2lkeW5Wc3MvQVFBV1hGektXMFgvRHFVdjdEbnJONm9Oa0phSWVPUzNFZXloSjNnTmJ6WkcwTk13WUF1L0YrTXh5ODEzT2U4NXkrWnlrQ3VKd1RHMkRNanlsVFpRRXpiZ0Y5bGFBbXdPZEJsTGt2TGl4bHVnK2RBd3JzWTdFeHZaYlZ6VXdZMWdOMHhsdTBHd0NvN3U2OTYxM3YyZ09PemU3UVBzYU1GRkF4QmcvblhiaGVXRGRZS2t3TEZmc2gyRkxaUUNqYUFBbWVvWjZXUkxmWEwxZ2xFbGc1Qmpybi9VN3ludExuUGZTZDhPVlk3cngvcFpOTmdWTUJJSkFZdWgvblJldVVOdVpJV2d3R1JNdGdaajhyYVZNQUFyMVliN2dhYU0rWUpzRk5jNXV2NGhqYUVwNzd1U0lza0xUa3I4WjBhV05BeXp4eGkyaFRRSkNHS3NEVE1aUHhZWkw0REVJWDB6TGRqNUFsdURHdWFQcVlOMDJlb0ZJMllTZllrNVZpS1JIWVROZExTYUNvTW13QUNDMHJ4L2FFR3dFaUtVY1FKVE01VjQ2Mjgxd0NZYnhuNlQ4VFBsZUthK3FySEcwelR3RlFjWVhNcngvMW1IdkhzMW1QeEJrbENCQjRta2ZSQS9nRXU3cDRUMjZIck1FQUVBSkwxbTFRbnZld0Irb29BeW5iTXQ1QUlJQTFXakpTZjFxNS91ZGUycm9BelBaQnJIN003VEJQQVNsbVdnaENqTXNFQUNiQVkxbFFQMEFCeUpPWHhqeUNOOHcwL2NhekFRWGdRUjNWbjN0bGZENExuSDRuK0ZOKzhRM0FTYXhMNGlxQURtTU5UUVNWR2pPbW1jcVAzdHcrY2F2TUxZSHo5enlKeDl4eGVQUThBWFg2TXJkR3BaTkxnVk1ESUpCWVlKYVBFakZaWWhqbThDZXhTSXptd0p3L3pmdE5Bb2dsT2pHVlpyR2YrWFVSNzh5d2V5WGFGRXZSVW1LR0ZpUTNKdjVwVEhQOHlKRHJoQVV0L1REQmdRUVhvVTZMb3lrbktsNThoN0pwajFtSEFSTW5mQUFLUWs5UTQxSUNZcFptcUVSZ0VVREtUb0NtL0hGVjBHQ2pRUXZFSTR6aUptSFdacEdSZ0NxYWNBU0wrNVJKUUVlNEVkUjVGcUhsK2dqZ0l1VG4weFdYM21tZGM1N0xsTDhFV0lDMStVd2JRcFBHckkzRkNHZ1RkYlVCZFN3dlFBUVhSYXdBM291VlIzNzV1Q0tBV2FCc2FRWlFRSmUyUy9tc0FuZ0EyaERtU2NDVU1oTkhrZk1zWklRN1dtY2hLc0JCWFFDQ3hPK2s3dnBVbEJQYU5FdUMrck5vUE9VcFQrblBVRjVtRnVSejZ3Q0RNbGdxTXYyVUJjWTVsaFA4akRzaWNSWGFVUUs4dkh2cTRobTdtUFFGdEZoS0xIL2NSWlZPTGdWT0JZREFhQTNhd3dUdW5keW0ySHpOdGcwZ0FEUW1WSnJrbUxLWVR6Nk9NMTdMZjlyRlhvQU80eGZNTmliV0FrSmxuZ0FMR2lRUXdieFBXOTNydVh6ckdQTTRaUzdNSGNOUDFIcG1nakJYWDNIRkZaMkpZL0JNMkRRbWZtcGdJd0dqUzZaeGRVSWJRaVMrYmhva3N6dnc1SnE2MEtZbFZoRGZYU0RnckQxaFpvdFZEVk5uZWZtOFBWZVpoQ3pnRTdPdlk0RjN3SWt5QUJMQ0QwM01Ha0J2NEdIVHZuRmpEckJaU29RelFEYW11QXZRVmRKVzZnNE1lVWNiNGVpOVFqZm5URnVVdUg4Y1cyQW9lZnVGRzM2MHJmT2paVUpaenVFUnJBTGo0a3BBcm5pQ3NiOEJwU3dNM2d0ZzBGWm00eWpEQnR6YWEwZGpMSUNPbFROSkg1WkhtMHNKbGdWNk1GM3ZEQXpyYzJJYkNOS3NCYUdOWWhWaGhXR3Awb2JjUktjdEFZd0JUdk4zWTJVNmlWT1A1L1U4eThlN0FDQnUzQWJpdnFreHpLa054cWxONTVxYTFqZzE3WGRxWnJHcGFVYjczbGNYTDQwQ2plbE56ZHcvTlcxNWFrSjFhaHJhMUJqajFMVHNxVTF4bkpyUTNmTUIycWtGU2szTkhEczF4amcxUmpHMUJZV21CZ2ltSm5pbXhtajd2VTBnVE0xMFBUV3RjbW9hM05RMDNrbDdTNDNSVDAwd1RzMGRNalZCTmJWZ3hxbFpuM3BkbWt0cmFrS2s1L1BUbVBMVVpsMU16UVE5TlcydTE3TUZOazZOZ2ZkKzB2eXVVd01vUFgrekJFeE5XNTJhc0o2YWIzbHFscEtweFN4TTN0ZTVKc2luSmdoNy9kM1FCbEcvYi94cHB0ZXBDYWFwQ1orcEFheXB1ZGQ2dlp2N1oycEJqRk56V1V4TjJFL043RHkxd0xHcFJlcFBEU1JOVFNCTnpWVGVpL0lPRFJqMS8wMGI2KytHeHQ3Yjg5c01oS2tKcjZrSnEvNSt6VFhUYWFRTm11Q1ptaHRvYWlid1RsUFBVSjlOcHhZZk1EVlQvdFJjTDcydVRmQk5UU2oweDNobmJUdW1GdDh5TlRQLzFFRC8xRmJlN0czbm5kSEx2cG41cHdZQ3ArYldtSnJnNzdjMkFkTnBqRWJOYk4vSGVKdUpNVFVMVXM4N2x0K0NUUHYxRnZoNy9qUTZLMHQvYkNEaWdqbzFDMDd2dDgyOU5UVXIxdFNFUWErL3Z0YldqNW1hVmFIM2xXWXA2dVUxUURjMTREWTFpMFBQcTk4MUlOMnY2WWR0ZHM3VTNIMlRmb3N1RGV6MVB0dUFSSyt2Tm12Z3FiZEpjNjMydnU2WmJmcGk3MThLYXFDbDk3Zm1lcG1hdFdTeWQ1KytORTh0VHFmM216WmQ5L3gxNWVtVExVN2ovTG41ZlNmbHVJSG1QbzcwaXpFMVlOcHAwRDVwUDU2dS8wV0I5U2x3R0lUSFIwL3pwVjB3QmRNTStBYjVWODlxUW9PNXlYOVR0QkJYWW5hR1o5RFVtR3BieS9adFA5ZEZucDlBS2VaYTkvTXZaL3FjY2dTdXNUcFlWTVlNQnFaOW1yVnJjUWNJQ0JTMXpWYzkrbEc1Q1dqNjZwZ1VzemFOVWhtMGRmdFlBdlFaZFJvVEY0WThBdi80cjJtbHB1bHh6OXovL3ZmdlpuUXhDN1JkL1c5TVpqc3dXVE50VzJuUmdrTTBZTzhSalRWN3o2QnhLb1BKMXJHTmF3Qjl2V2RNMkRubk9qY01xMFZXUkhTT3k2QUoydjd1TER5cEY2Mld1NEVGd0g0VFNUbDgvdDVEYkV5bVYyb1B6eFduUWtNWmswWGRtbERvN2l0TG9yUGlhRmRXQi8wZ3MzQUVZZW9iNGd5OGwvZDByL0V0bjNNc0JmTWttRkFFLzVLMVNtd0RPbXUvV0dKWU1yaEhsRWZMMTBhc1dSYUVjazc5NUdXbGNLeGZjUy81cjk2c0VDeENqajNUUHUzS3FwWFZSZlZaVmc3WDFWK1FicFlwZDI2MFhuZ256K1FXMHVmU2hzcmc5a3ZkdVZsWW1QUTFscmM4bDZVcE5HSk5POGxKOEt6M040Ymkza2xNekRvQjBpZjVIVTl6M1hiQkFnSHByNVg0T3ZuRW1jQU1ja0xtTEtadEFRZ21ZVXlUdVJ4d1NHS094Z3hzUzJiOTVMUG4vb2hQTy9jdzR3cVVZN29uZUoyUFdaZXd3dUF4Wkh2Q1F3QmlUTXR6TndvVGVXSmdZbkpXbnBrVjRpQ1k5QU1lUE5lMWNYcHZUTzBBUjRUWVVwQWFaZzZNekwvUW1Sa2xnRWsyNVFUQWVKNkFPSDBWT0hHc1BtSUQxSStwMnprQmN3TDNtTHlWNHh4ZnZIUCtaeU9zQkdJNkprVGxKZlNzazNCdG0ra0NZQUVmeXZIdVdhSjViSk4xLzR0eElMVE1FbEFmY1NLcFl3UXVzREFtNW5wK2Z3c0dBUi95ZTIvbG9LUFpPMUptR2VqRDZXc0FtV051SGRlWEV0Qm4wUzZtOFhGMkROcDRmL1R4VEM0VGZVdC9BQW9Bd253L3duTUNpQUUvdE1wOTl1b0pPUGlmRFYzRlplUTQvZGY5Nmd0MGVJOW13VHBQSjg5Sk80dlZTT0tXdzVpVnBhMlUzU3dkdmQ3ZVFkMnRrZUU2c0dUTStHLzhpZjhDZ01TSkdGL0FaQUJJeWo5cGUwQmZMSkI2MjdoL0JKQldPdmtVT0pVQUFsT3dOcjFJZjh3Sk16bUxhVnNBZ2thT0NXT0kwWVpDWHdJampDdm41bnVSMVJnZWdFZHpvdldKTVhBT2N5WllNR0FhcUNSaVg2eEExbFFBWEZnc3RDMUdic3JiUFBFOUp3anhIaTFhSDdPbXhkSkNKU0NJTmhkTkxReWYxVXJzZzdyWUFBbWFIMzg4NXAxVkQ4Zm5FUXJuMm1xRDgyU3Fac3F4SDMzNjQ4SmNhTWhhb0wzTUVFbVVmVDVhbHRnZTlmVmVxWmY4eWpRclJyMGR1MGFMenpSVndNbzV3dDc5RWtzTHpmVlNsblVYYXdBTUVjeFpuOEJ6eklRaUZMV1JZek1NeHNUQ2tyWm1WVkYzV240RXNqNUZZTG9YcUJCQVNxTjJMRS9XZExCZlNxYitpUnVJTlFzUWlQVkdHWVN0QkRBNEptQUJWdi9OcHRFZldCS1VnZTZFcjNQcXBUNENGK1ZOY0tiLzJlVFJCZ0duYVRmUDg4N0dqS1M5QWVETU5ESkxSQm5pWGxJdi9SVUFCZ1JjYzY4WkYxSldGZFVYQkZVQ2owQzFkcmMrQ3dDYWZxcHZIbWJGMUY3d01mNmdDU1VCVFl6TlNydEJnVk1ESUhROEs4Y1JPZ2F5UVl5eHpUWFQzV2lXemRRU005dUdDd09kQ2ZsUncwdU5NVTFNaStack9XcW0yVERLNUFFY01Fb21hWUxHeHBvd0N0aG82cXdDZ3Nnd1YrOENTR0NvOG1LY3B1dEpua0dZTVgvU2J1V2h5VWtFQWxyRVhPcXJsOHpKZ3Z5VUt5L2hoREZicUVtUXBITnhhV0JvaEtMWkdLd0k0eGRXQ1RqQVlzbWNEZ2dvaTZXQmRvNW0zcFh3QTVTc2hEa20xZ2NDd0RSVjRFZ2RtTkpIK29sTVZ3YlhpWHB4elFqRUE1Z0JKYzhaRSswWi9UeHZ0Skl3YlFNUmUwWEFqMlVzL2JkNFZtaEhTTFAwRWNEcVRQamFhdy9QVFR1a0hCWkIxMjJFWGF3Tk9XZXZiNHpIUUVTQWgyZU43cW1VcXcxWVF1STJZUDVYQnNGdnI4OEJoTndnK2loWGhuNFhLd0NySlVHc2Z3STYraklCalo4RVlDcUhSY2U5QVo4VUZTQUV6d0dHOUZOMVNGSXZ0S0ZaajkvT3lIWFBBZkFzOE1VYXBVNzZtdjdIZWtFYkJ6QUJxM3hPM2d3aWRLZXg2OXNzRVFFaUFMeGdYd25RM3VRSDRWTG4yaGNGVU9CVUFBZ1J6Z1k0b1dNdzg1Mk5UUGVzTnZXMkFBUmd3RVdBVWMwVGF3QUJnbW5Ua09UQmRBUGthSFFFTG9ib3ZDMFIrSzRCSGpsUFVPWi9oTlgxN2ZzYnpNR0VZbnp1TkhYTTFMUGlueWFzazB6aG85RVJaUHlzN3NQTUFSRGxlSTRaRHVwQlNCRjZtYnFYTXJMT2dyaURNR1RNWFAxTTJWeEtMQjZ4amhEMk5FUjlGRjIwalhzeno5Mm4zVjFUcjZ4bjRub1dDREtkandicUhHMlVBSm1ucGVtdnpQSk0ralRuK1ZSRkFQdW9uMHMyRlZKZHNwUnlYRTBBblBZbFFBbE5OR0NKR1JOQjY5N3MvVi9hQXFLWTd3RXh3SVA3aGtYUm1oNWpRbC90ci8vUVpvRTJmblhDWDluS0FqenlIUFZDYitlWi9nRXo1K0pPSXRDQkVRSmFIdThFSElqTklOUmpKVkVlRjRpOWU4VHRBSlhhVVFJWTFFc1oyazArYmhyMVRkSkh6REpoTmRMMzlBMUFNRzZxVE4wRXFzVDNTQ3d0eXRMZjNadCs1dDI5TTh1S2hGWlpFcnlmcUoraXdBWXBjR29BaEFWYUJCVlYrdjhVMkJhQUFNNHdjeHFZWURBTWtXWk9TR05xTmd3OEtUNWEybklBQk5DWDJBTE1Gc0E0MTl3QTdrMVFXOHF5NTFaSWNKVmpqTm43NVNOR3RFakNuZTg5SnUvVUFWTW5MRWEzZ2JvRkZBQWJHRzhTc0RJUGFuTk5vSjluQTA4RWpXZGw2bWZ1SGZlRXdQVU44RWdZdW5zRnZMRjJFSjZKRTVESE5ab25MZFQvVVV1bkZUc0hXTkNPQlFKbS9ZaGUrQTAvaE1VNEpZNmx4RDBFY0xSb2dJVFE1ODRBcFBaeUJZemxMdjIzL29mMnR3RmhyRDRTT3FxcnRnRFFXSHZtUzMwVHBOSDZnWDM1YllDZXZYN2hYZnluUVJQUUV0Q2liNmk3dGlkd1daRzRiNVNuallGSmZVd2kwSlVCT0VRWXh4b0JDRENadXc3UUtjdjlyREtaQ2txWUp6OEFrT0RkQkVNNkIyQ1lXaXJvVjFteFNoRHdXV1V4d2JqYU5FdVJBM1JvbFRwdzllZ1Aya2tzaGFST3dLMTZLVXNBYmhadXkvUmo0TXk5UUlyM0J1VFVnNFhGT2kzKzc0SXlCWXdEdEVBdzRNbDY1UDBybld3S25Bb0FjUkNKRGI2em1EWUpJQ3hZeEx4TzRBQUN0RGJNS1J0aGdhSG1tSUFrd0RGOGNRNEVBVUVvRWI1TTF4aDNOR3h4RUpoSDdyZVBCWUoxd0xzQUtzNFQ0Smd2WmsxckJCNlorZ0dWTEt5RUNXUHVYQnpxeXVUdlhneWFvTUp3SFJObW1QaVlDTmdFODQzbnhkYTRod1dDeHNlS3NsL3lUclJHUXQxOWlVY0ljRXJzUUlRRUM0bDhQc0djSUV6SDRnUUFEMjRiR2phQkhSLzMrSHkrZnFCQUVwenAzcmdWL0E4b0FaZ2Myd0k0dUJ0WUl3aW93d0J4Sm5KbWMyV3cvbkFkQW5QQUNrdU9OZ09nWEVlM01RRkt6bnNISUk2QVo3WGlybkxlNW91bmhMYytaVTlqQjRZOFV5TG9nVHg1OVRPclh3SU1oQzM2SnFBUmVOSFBuTmYvdEQrQmpwYmFHWmd6aStYcXR2cW9QTm9vdEJQblFEakhkZUpaNG5DOEkwdUlzcHdEVEFVTkF5V09iVnh0NGpBSWNzZG00cUNyLzhhRWRnUyswWTZnQndnQWNMTlp1S0tTV0JpQU1QVnpyL2RpOGJLUVZjWUhzQkxMaVR5RWI4WmlMRndwN3lUdUU3RE14U1RnbVhJUnVta0xTZnRUSU13eUFqcVhYRUVuOGQxT2U1MU9EWUF3WmN6QTVPODI0R3dZQm1abW9KL0Z0Q2tBd2J4T084SlFDWWFZYndFRERNdHpNRitnZ2FuWHVXeGhaSzQ3eCtjdUNEUDNZYUJtUVdpdjNET2FtcDNUaHNBQ0UvSzVacVhBYU52NkJsMzRleVlCQlZEd05RTURORFVNV3RtMGRXVUFQcGc4Z2FGT1RPeEFqMnZlYjB4QWlQTzA2SUFMZm1ybk1PdkRwcmhwYU5BQWxQc0phSHZBaDRDSmR1cnJualJiNENpSnkwUGVVVmpGWE81OHByMGxQNmJxUEdIT3FrUExKZHljSTFScGRLWUdjdk01aDBtTEpkQ09oS1RsdWhON0FDenVsOFIzc1BRb0g3aFJIc0ZLY0RwT01DREJOMCtzSi9MTFk3Vk1iUkh6Zm9TaTYrT1cvcU9OTGFnVTRaM1pKSlFFZlkrVmdORGw0c200RjlpckxBRzBnQU1Bay9LYzExKzRBZnhIUS9SV1J4cTlmcFVnUzlmZGI1OE51RU1MTGhEQUZCMVpHVHpMT0VIdkVaRHBXMXhSOHJGMFphb2lFT3g4aEtueDRGMjVydktzSzVzVmk2djJxcXV1T245T1A5SnU2Z3RFc0ZERnhiSUxRdGI0MHY3QTlEeUpqUkd2Z2c3ZUxjQTBBYXlVaGtySFM0RlRBU0NZdnpDZ2FLUVlpVTZXNlhsemYrbnhrdnpTbjQ0SjhXc2V0S0dKS1hPWGttS3V6ZGNSVXhZVE04MlFOb3pCRWVpK1IrSS9aaHFtaCtHT3JnM25DV05BSUVMZ0lLSGhIa0xmaGluYll5YUVydWNUbEhQUW9XN2VYMkJaWm4wNFIyaU9pVFZGK1luUnlEV0NpSldDRllQUTFyY09zNzVGN3MrZWdLWVplMGQwQU1SR29ZcXU2RUFMWmltSnVUNzN4L1FlR3NsTG9BSEhCQkRtT2lZYUd4RGluV2pwOXZJVGtOb2k3WVZobzRkTkhnSXIwMTREbHJoczlrcmFUM214b21oL29DVnRyYjVvTi9yNlUxWmNSMXdFOGhQbTZRdnFZZ3ZJeWJHMkJMYThyM01FWnVJTVVpNlFwaHdnTWZmRjBqUUNobHpqTHNvS2tjNnhjQUI5eXZBL05IZE5uOHU3NVg1OVVUQXF3SUN1K3FCOHNWNEJjbnZSa0FWSDRHdVN0VE5ZUkNRdUI1WWo5TlVmOExPMGsyZmlhK0phQXNUR0pjdTVkOVJQdjkrRkJGenA0NERhUEFuNk5WNkFYMzFsekJNTFhjVjN6S2wyZVk5UEJZQ2dZUmpjQmc4enNJSHN2dzRIbmRPYVQxT3k5Z0ZMeTBFYkJyaU94cnhFbzNzMGMrcGUzN3ZBbEFrSkVlTVNwb1g1MHY3RFpKbVpNZGd3UUF5V3Y1cXZtdEJKdm5FdnJ6WWN5M0dkYVRZQ1VCN2FKOGJpV2o2ZU5KYVQvMXdPbURWNmpFd283d3RrMFI3SGhMSFJmZ2hqZ25vK0hYSE1lOUIvNW12OWszWklBR0wrTk5RRWZBSW5oQjZORjlpZ3hVdUpIZkVlTkgzM1oxcWZld2laVEVzYzYwQzRBMG9BQWVZc0VlUkFFYkJONDFNbW9XelA3U0cvLzZ3OFlnQUVYQUlWdEgxdUErNFJyb0p4U3FENEEvY0FjL1kwZC8yQlcwcmQ1dUFtZFRRMjlRUDMwSmExdFg0ekNubmcwUFZzeHJHMkZrekpjc09VVHl1VmdNQllQSlRqSG1YbVh1K21EWE9jdlNCTFF0NHhLeHJoekszaVdQMk1yOFJsNUI3bDZoT3BhMmFRb0VVK0FpWXZhNmgreFMwM1Q3RVVKVzdFZGFaN2ZRQXRDVXp0aG83R24vSzRlTXdNb1R3RWxBR25lVjlqbFB0RFB1TnRWNUkrcW04dkplL3AvZEI4YWR3YTB4VEZTc2RIZ1ZNQklGZ1lhQ2RKdElkRUpRdHUwZ24zWW1hNTV6VHVOK0hDNEMvUGVncHpHbUYwbUJzaEl4SHdDV0IwbnVaa2k2dkFPUnRCd0QzZ1AwSE5YQjZBNFJ4aGl5RW12ejJHSFlzU3N6QkJFakRoT2syRjhNV3c0NXNueExoTG1IMHhjMlh3K1JOZ1NVeW9naXdKaFV3TnhOaUJEUUtGSUlqd0lmQ1hHRm5LeWw2WkJEWHJEVGVES1ByUWhSbGEvOVFubGEvdTBYUlpETlRGdWRHS3d4enZYSUw0UEVkL1o3NEd4Q1J1SE5IL1RQbGNGUVFRU3dJUXBoNUo2RUhJdTlmZXM5V0ZNS2JSZTQ3TlRCdDBRMWRDak8rWmdITE5OTjRrd3BEdkh5QmlDV0xTRjQ5d1VBQmN2dGpwR1FtWXpMUGpka2s5dkN2UTRMdzZTS3hLNnVicm1lZ0c3SGhuZmNCOStwTmovN1c3dWdXME9NZGFrWmdiMThXSG1KcnBHbnJvbzJpVmZxbmN4T0Nnblh4cE43RXVtVUlaV3V1cnpzVWFKTGlSZFNocmc4d3RCQWw0Vks3K243SWQyOVFSZU11TWpOQWY2T1E2WXRFUTV6TjN4eVhmU2QwYmk5eVE0eFRqMUZWY0NBc01JRDhtVmgvMHhPUFJ0OUx4VWVCVUFBalIyYVBwbDk4N244MWxEc1FRbUlmUFd0b0VnTUI0OXpMREpnQVNreVUwbWNxanlZNk1MNmIwbkxPbktRRUo4bU9LR0xiNktnY3oxSjV4ZjJDZXVmY1p6M2hHYjBieERHSWNNQjlBQWxCUmhueVlyL1ArRS80RWYrb1FiZGt5d3BndHdVQ2JKMHc5Ujc5eG4zY0tRQUdVMU5kNUd1dCtpZlpPSUhvZWpkdzkrbCtlNjlqR0QwL1laam9ra3oyTGdQTXNCSjRaUVVJNEFzSmpZc1ZRYndGMXJBWm9aekNydC96UnBPTy9wN2tTdW1qcVhWTVBlNkFseVR1cmgyZTdSamlPS1d0c2JNTC9ESmltemNiNitCK2hyajlvdyt2YlRCVkF3bnNuSlJoVS8vSHVCTDR0OTlzRFdDTndHSitERm83MUhYMG14Mk1lMmkrYUp2QlRXd29XeFZmU1orUUhSaUs4Z1NyOUZ4MERqZ0FsN2VwZEV2ZVE5MkRkeWpQMUdYV1JWNzJjVDcyMHQyT2dLVURXWGwvZmhYaUh2Tzk4TDVqVWU0MEFtUlhOT2ZFbEFGdVNmZzA0QWc3ZVc5dm8yNVdPaHdLbkFrQ1lyc2I4UjFPaWdWM2RBcmZicnE1MEFBQkFBRWxFUVZRSUJob1pnWUFwWnNBZEQ1bVA1Nm1iQUJETTZUb0pSajRtYmdzRFBKWUUvMGRCNzlnMmFsTFI0S0ladWk1U0gwQWg1REVEbWxnUzVpK0NYajRNZFl4QllMb25aR2w2UUk3Mng5d2plSHcvQWdOM1grcENLSHFXUHBKejV0WDdUNWhIczNRY0FaeFYvNENkV0FWaTNVbzk3Wm5SV1N2Y1M1aUkvcWZWNXpuZVMzMUREMElmN1FoUTBlWGFpbFk4VHF1azJTdURVSmxyOUZsZU9lQWsxaE43ejJSOThVelAwMzdPRVlZQk1zeno4cUFQelRXSmxxOXU4cXZUbUdoK0QzM29RN3VsQW5qajBwZ0hjbzc1RC9vZmR3eFhncmIzekxnTTFJbkFEQkMwakxqcjQ2SlUzaXR1SU8wdnpzUGVGemZsVlQ4SjZPTmVHUHRuMWxOSXZJZjhObE5DQTR4elR0MEk4UUFSejJHaGNSMncxRWNpNURLVFJ0c0tncFd5Z05sZVNneGVwZDdxNUZtaHFiMW5lRzRBY09JZU10dkdiQXpYV0NKMk9YRlJlVmRqd0R2cGw2dzBMQlQ2bXZaTHUzSUpjbS9JbnpHYlJkOTJtUWE3V1BkVEFTQVFucDliUnpNRmpxYVZxVmNZS0JSN0Z0TW1BQVM2WWFvR0s5TzFxUEJvdGZ5MlhFTzBMZGR0aEVIK2ozc00wakZOanZDM0YrQW1HSkRMUWRuUmpKMmpsV1VhSU1aUDR4Z0RPZm5PK1o4eDE4eTBrQzhDMzdNQXh3aDFZTUpVUmVmNXkybUN6dEZtQUJEbmdaVllHaHhIK3haWUp4K1E0VHlHcmF6NG9ybGduS2Y1cTR2UGZqdTIwYXJjVHhBU1FrQ0l2dWxaTk5rSVJDQkJFTjBJb0FTbE1rL0gvV0hOQ1lBNFFJeEdUck5kU2x3bGdoVXhXMk9EQUxZQmhGd1Y0bERVQVNCUVR5NkMrUEJkQXpZQW9TVHZDb0NoT1NDbjdTSzgzU2NnY1M4Qm1UTEd2ZGs0R2FQNXFGUmNWTnhUNnBSMjhaNk91U3BaR0tJTWNBR1p0V0JGVCs5cjlnZGhUWmpxQytxYUdSak00UUVRM2szZ0lSQ3N6OFhTeEZRT1lPa2YzcDB3dHhDWFo5djBBWHZqeWg0ZDlRWENpNXRPMG9hRVBGNTBiVnV4TWdtd2MyNk1lOGcxZlFPUTVONUlPYTdoVy9xb1o2VWZ4eHJoUEVIcldxWTZwcnhkM2JNNjZMTkFmdHlpM2tXY2hQZTBpWHN3dnJTOXFlQ1NjV29tVGFYTFQ0RlRBeUNRanBZV0pJNXBZNXhNeW1jMWJRcEFvRi9tbmhQY1hBeXNPMGtHTzBaTUd6YXdNV2lEUFF4Ny9HL1JIWnVBUUVLY3BnRThzSERRaXVYbDFnQTQrTy9EUURGM2NReUVSd0FONFJFTFE3UnNXaWROWHpuUjlnR2NNQmdNbkxaRE9DZy9RWEFDT3ZuQkNYRDNLa01kQUFXZzFEdU43eU1QK2lhS24vQWsrQWdnWUNlbWEvbFlQQUFIQWhpTkNLeFlZUVM1RWk3cVN2Q01GZ2owemJSS0FBTXQwRGRDaExiR1NyR1UybWVvTHdvZWRvNndDcDNWemV3UDdjZDY1MWo5dFl0M0dZVVppdzZ3SmdsWVZTOXhETTRSZnBuUzYzd0UvRks5QUJGZ0pXMFV3Q2xJVXlJTWxJbE9CQzRCcmEzVWlYVUNEYjBENEFyRUFMUlNGbjhTZkprMjlEN1oxREg5d1RsYVAzb0RCZHdpemxsN0lsWW14K2ljL3BkeTdQVURJTmYvMUIvSWtWaDF0SlZyYzZzZEdtWWhxSjc1aGg5MVVRL0MwemlLQlNMYXRYZm02Z0lXZ1FwV0tYVUFZRVpCTzVaNTJ2NER2dHJDT0tSOEpLN0srTlQyZ0hhbHkwK0JVd0VnbUZiblB1S1EwalVSMjJjeGJSSkE3RVUvMmc5bXlmUTlSbjlIa3ljTUFpZ0lNSGx0TkYvQ3dmOEVoaEV1dEdLTW5oa1pVeVhnc3dDU3ZJUUo0WnlncXpEWlhMUEhYTjFEQUNqRExKeG9LM2tQQWdVb0lUQ2k5U3YzK3VaclR4bkFTTFIvNTJ4aDNnRVRoQm1oeFNmdU9vRkNjeVlJdkxmbjJBZFFqRUlNMDB1NXRINy81LzBZVFFoVDF3aE1RaFdORXFzQjVBQWozaU1XQU45MFFGdUN4M081QXhKckliaFR5a3FHeWlXWWxNSHFFOWVVOHhnMXNBZVV5d01JZVlacjNFdjJMQUpvektXU2QvVE9lMDJkSm5qMUNYNXY0QTl3QzBqS1ZGcnZJazlpQUFTZEpnRW5YQnNFdHY0RXJKbkt4MUtnTGRScHIwMmJCWHpKNDUwOFI1dm9WMmlxL05IcWtMTGt5Mzk3YlhLdWFjeHhoeWxiMnlzSHlNWjM1Z2x3WWhHWko4QTRaWE1mNmJ0U0xCMnVLUnZBU1FMQXZmdFpTY1lIR2hzUFNma1NMK0RsK3FZUzRDZk9oRVZNWHhacjgrUW5QM2xUeGE5ZGpqNXBEQnRmeGhwZXV3UkUxeTU0QXplY0NnQkJnNkNoTEtVc2Z6eGZEVzhwNzJrN2R6a0FCSTJJS1pvd3h0aTVHUUFKZ3oybWFBeVFTVGhNRXZOMTNYRytNQmphR3l6QUFjRWt0b1Uxd3IwQzFQSXRDUGV4SGhBaUdEc3dnb2tRZU5xYlNadUZoS1ljVFpHSmZVeVoyVUI0bVdFZ0FRc3hsM3VHT2hKeTBVS2o5ZEF3V1Q5aWNpZm9tS3RqRFNGYytjaWRaekhJZTZ0cndGVE9aWThtL05vRU50ZEZFZzNiTlJZMUxpTnhBeXdpN2lNQUNVUldGWnE3YzNFditjKzFrcUJDZlFGQTBGNEVKYUEwTGxMRVNnUFFFS2JLZEIvM2gzS0FPUFVHdEZ4amJaQlhYU1dnUmo3bHVTZUNQMWFGdkl0MmtRK0Q1cllBaE93eFJ6UkdWMEpTSGxzVzB2SWZLQnNUTUNXZ051QkRuSU4zMTJicFcyazM5UWZvVXE0OVpxeHZKRERST2ZlYlJlRzlBQUhuOUNrV0cwQjVuSGJzblZuQ0FwNzBXYk1rZ0VrQVpKNHlkUk45bGxMY1k1NDVCeXVZOVBqdEUzMGg3N0JVMW1rN3A1MjlMMENNdDBUaDhKN0dPT0E0NzJ0SHBRSCtBNWl4N25DZEFJZ3NwSjUvWEVKYjN6ZldqVWt1VHpGWTZtUHRrT05PT3dzZ2FId1F2Y0hLYklqQS9vOGJ4b0hSWWV3NnhsbEwyd1lRQmhpQmdoSDdnbVFFS0dZM210cDFkaHNoTkFwVXdtcHU1aDNiaUdDaFlVc1l1UCtlRjRHbFRKcTJLWVJTZk9ubTVFdkFnUGFQMEJhdHpjMFZ6Y1g5QmdEd294N01wTTY1SjhHVkVVWlpxZEIxNEVIQzlJRUtBbk5jK0FnRHd1U1pwdVVmTjhKWFgvVk1RakFXQ2VWYzNZSi9NVUw1Z1NKSklCbVhTeEtUTFVEQllwREZvT1EzS3lJQVM1MjFSeEp0V0I3Q2t1YlAvKzlZb0IvUTRqOUJpSzRCT1pnMHNFTHdpWG5RbHpCcVFsK0FxVHE0THdKLy9FSXBEWnpHcGp6eEVSbDdmTnZlbjh0R1VLcnhxd3o5QnMzOHo4YWw0bm0wY2ZSR1MwRjBTZDZCbFVOKzA0Y2Rpd2xBRitXaGdYNUorT3N6Y1N1a2ZMeEIvUUs4MGtma1RVeE44bkpUMFh5ekZMbTh5bU9ObWxzM3hieTRUeHNERmU1THdPVkJYOGJsY2dXV3RRVVhqM2RPLzJPWlFzY3Mxc2J5Qmp3dEplNGRiYWV2aC9aTCtYYmhuSms2K2g0bEpjRzk2SXYzVUFvVEo3Tms4VG5LKzRrekFsVG02Vnl6TnFuSHVLcm9QTTgyamhPWE5HOUhRQUl2SFpXTmJUei9vREozRmtCNE1YNTVtZ2VtaHRuNFAyNENqL2dkeCtDN2d3aHltcTV2RTBBa2VoMmpOT0E4eThEV29jSjREN09uc2UyVk1HaUJaUmloc21pRk5Fa3hCUDVuU1Y4TVBaWU0yalgzU1FTemE3UklBaTlDd3IwRUpkTmtBaldkRXhUSXRFL0llU2ZQVERueUUwNjAveVFDRUhnbGRJQUl0RkRYOGY2eExtakVsU0pQVXJSMThRd3NOcGhDem9sdllGa1JIQ2pGOGdCSUVSRG9vOTU1cjlCYmZRaHJ5ZXlRZ0RiQ1NINENLb0lwOTZDcmMzbGY1OVdkRmg4bTdWeUNQbDJMYThrOWdCek5TQUN6K296bEF5NWNKeXlGYUlnTzdzK3p1U2p5UDN2dm9CeDVqVzNDM3RoT3NoYUl0Z1k4QUNuMUhNdDBUOHJLOXkzU3B2cVBPcXVqLytKUU1qc2w5OHozOG5wZlZoelA4bnl1b3FVRWpQcG1CanA3Sm12SFhubVg3czg1NVFqTVpVYlhoc29pU0FNQXgwVzkzRVBJTUwzckg5NHJiWmU0c0pTN0szdFdSTzBneVByS0ZpVHJXQnVrYjluak4wejZtMHBjUStPMDVyRmNnRzBFc2VPMWJmMjNOZ25GWmluaG5WRTBscTVmam5NN0RTQkNJQXpDMXhvclhVZ0J6UGNncmVmQ093NS9oTjRHdHoxR3lZVkVnM2FPSUEwREhnVVNNemtoQ2RoWm9aSlFKOUJZRUFUa3pSTU5rdllYL3ozQXdQS0VJWHFlWjJDdWVaYjhvdUFEQ2d4NGxndUNPQUtDNWtaREk4UlpBTnhyUm9BOU1PQittam1oUnVqNXdCUTNpcm9UQ2tuNWtKUDdnSUxVUVJtZTRSN2FTalJTMTFsRXhwUjRncGlzRXhCSWEwM1V2WFBhMGZNSURqTUVZb0ZRSnBPdWZZUTVvVUZZT1NlR3c5NjVDT25NRUdFOUNmQ0llWjlBOXA3dWlZVmg5TSt6TExqR2VtS3Yzc0FaLzNNQ1c1MjNtUTFqMWdlaG4zUDIyanRUV0hNK0FvSFFKL3h5M2p1aG8vWk8rZHdvbUx3OHpuazMyanFMRCt0ajdtV0M5aXpId0FmQnE2Nk9NM3ZFL2ZHcGV6ZmxFTnB4aXdDWWhKTTZ4UHBGb0dlYTUwSGFxTEwxdFR4amJQdkQvazlzamJxeEZnR3RMQ3hjZGZPVWIwUUFjUkt0WEJzQmNNbzVpWW1sVDRDemZxSXZCNkNxSzJCbzRUQXV3ZkFSUUpXVndCZ0ZsclJuQVBZbTNrOC8yR3VORTViQWVaRHpKcDY1WHhtVWtiMitTd1A0c3FBZFp6b1ZBR0tKZ0FiUlNSMDBTL1hkeHJsdEFnak1XQlM3WkVBYnlBWTZadUIvTmd5ZW9CTHdGbjl6VE1HRUZMQ1IrekZJWmwrYUxMT3ZBWXRKTURjVE1oSXRLK1pvQXlodUU4L0RqRHlIeG96NUV3WVliK0lhc3R3MTBNR01MaEdHckJkTTlyUjI5OXVQZnRiRVMzZ0dEVFJyUkRoR0F4WUR3Q2dDeTNuK1V2RUcvaE5lRWRJQUJqY0ViU3FDVUI1MUd4UHpMSTJUQ1Q1cklEQnZxMThzQ280SlkxWTJ6OG9NQW9HUTRpSXdYYlFkYVVRUW9rZmlPVHpiQm5TZ2xmOW9UdWdxWHhsTStvUjdCQy9Bb0F6WG90V2pnN2lVbElmQml4SGhNbUdhSjhoRytnQ0FnS2Y4eXZFL0sxM0dnaEdRS2c4aHJpL2xlVncwNnVnYUlKWllwM3liUTMrUk4wSlZ2Z0NnV0hoWWNKSThYenZIUlFBOHVpZDlGamhKZloxZldrSThaVjNxbnQrZDM1OGdBMEFCS01lQU1KUDI2QzdLczY2L0lmaFh2ZWJYdFo5K2U5SVNNQXpZWHR2aWg0eTVXQlFEZ0l3UElISnM5N1MvTmdqQTFBOEF0U1JqMjVkZFdaNVo2dFpKRkFqYlBBR0JucW5jeTVtNEQrT3E4bzVpZExTeHFjUDR1K1hOanpQdE5JQXd5RTBwTk1pU01KSUU3MkZZQklRQmVSYlROZ0dFZ2N6aWtBUUlvSGUwV29QTllrb1JHZ1FXaGhBTmwwQ0k1c20veUNKQWtCQzBMQWltRnlyRGhrRzRSc3NFS3B5TE5ZQzJyeHhNa2dBdzBBbHBHcnRyQkIrejR6MmFUMTBpY0RFdFlFZkNwT2VXZ1g3aGhoK0NuZURnajFZSHovYnUzR2JNMkttamMzbWZuSE5maEZYT0FUOHNINk13eXJVc2hvTUJBZzVvQjJTRlpqRzlKMy8yQUZEY0RON1hmYWIzRWRvRVM5cUFZTkUrQnIyNk9tOVRSNGw3Z1RWbERCWlVSdUlUbUpIelRSRjVBUFM4czN6NmdMMWdMM3YxWS9rWll3cUFOOWFCMUQwQ3dUa2IxNFZyM0JFc1U0UkVudUc4Lzl4TUVtdEtMRkN4TUkxNTVZOGxKYy9Mc1pnV2VRbmt4THNRWkFCYUJJaEZqUFNoUERmdFA4YVg5SXBzOElmQTBEZU1BU0RZczQyai9aSytyZzJOazhUaW9GMzg1alJZTHJLVGxMeW5kNXRiWjFqR1dIZ0lTd0RVT3dFUVFERGdpcWVsSGJTZkthOWNSRmxDWEtBdXdLNlBwOTl4QTh5ZnN4Y3RBaHhIMXlyZWhGOGRCdzNKTG1QSnU3Q3drbTM0YVByNWNTdkpPd3NnYUFxWUQ0Sm1HVmRhR3lib3BiSjJQdzJDR2Vnc3BtMENDQXlMOEJHd2FKb2tab0RwUnlBRVNFU0RZd29Pc0NPTTQ2OU8vZ2dDeklIQW9qbG5mcjZ5YlppL2dRTUVZQWpNbmM0VHJMRTJHSEMwV3dHWXl2Sk1qSWpBbDVnN0FRckNUaG1DNFBZQ0VKblNDT0RRQUdtaEVYRDZXZW9WVFphbW1IUDJudXY5Y2srdVpmRGJxNk5OWHRmTnRJaVFpNWF0M3Q0NTkyTW1XZjQzNSt4WkRvQTZJRUtaeW1jcDBnOXM2cWMrYUpIN3RCUFFSaHNjNitNNm9LVWMrVEZ4NXl4aUpaOTJ4ZENjWTIySlZjU3g2OWtEUXJFd09SZHJTS3dsTENLc0Y2NnBHeERsZnpiOWdpVkVtUUUyZ2lhbCtJQURrT3dKbjd4SHlraDlITk5JdVNIOEo1QThuMWtjQ0NPSTFEWHUwSHlYUk43MG8vVGh2ZnpTK2dxbFJudXFONEY0V0NhZlJhL0N6N3hqWEdXV2JsOUtMRTNxQjFDSExsbkIwck1sQUlMcjR5UWxZNVFsTXNuNDVYSUQvdlZKWXlyanhnd3M3NGd2b0dsNGgzUHlhMGRCbGNhMWM3RTZjamNBSXM3bEd5cDUzbjU3NE5zOWdJaDY2SU1VVWVQbk9CS0xqUHFnQnl1TnNXYjhHSU1VclRHbTZuTFhiMmNCQktHRmtRWmxJeHhUTHliaVF5dEpXWmt3a2ZNNWZ4YjIyd1FRaENuVHVZNXRHODM4anVOSDlqL2FxUC94eFJNVzhVazdieU9vSWp3amVMV3BnWXhSSkorMnAyRVJiczZ4U2hoUWhJR3BmM0Z4R0dBV21ZbnJJbkVUQkJFdEQ5aVFGOEFVMGMvVWpoRVJEZ1FKa01Sa1NRUDBIRUc3Z2tkSEZ3Ym1sU1JXQTdQQmROVGZQYWFHNm8vb0ZVdUM4K3B2bnlockdvNWpkU2J3TUh3K2VzQkJ3bHpSTVc0RWRDUncwTVo5NmtwUSthKytXZWVCcGdma1JhamFFNVFCQlBMYkltUlQ3NXozUElHWU9iYkh5SUMyZ0VTQm5wbW1tSHlFY3Y1bjd4bnUwVzhTZjVKcjJzNTFOTkp2blNjc3hLZGtyUkZBaGZBSFFBbFc1bHQ1NU5VWDBBQVlTYjBTTitFNnh1dTkwLy9NRWpGckJ4QkVSMWJNclBtaGIyaVhDREJCZkZ3OG94dUt1NGJRR3hNZTQxbmlWd2h6MDBKakdUbklDc3JxaEhkNTMza3lhd2k5Umw2WFBQb0g4RVBJc3RiRWxDLytnU0ExYlJTZ0ZNdHpISW53WStFeHZnQ3lDRHVXaFh6RHduc0JCMmdsNWdtZ0grTnMwTlNtN2VJaVRmK05KUy9nZ1pXTVN5dDlsa1dOb3VCZTRQeXdTVDI1R1NrT0k2QTc3UDJieklkMmdJSnh6TDNyL2RJWFdLcE1NejJ1dEpNQXdtRFFnUXhpQXlzYlpHYlE1emg3blk5R2tBV0Rqb3ZZbC91NTJ3UVFoQ0s2RXBieG5VZHdCeGhraWlCL09JRVRSb0RCYTBPQ0JIUExlY0xERkVxYmN3YU53TDRJRkZhREFJOElYSUxEOVdpMktjdWVRR0pGOEl3STJnQVU1eEtESU1hQ0JwN25jazFrRFlJd0tIRUxZeUxNbGUvOWsweE5GQWdtTXRyekNib2tRcFlKRklQTE8yZnFHYmVBL0t3MDloaG9naU96ZmdtQVJzQndWYkNhaE9aY00rN3hYdm83czM1V3h4UWo0cHFwb0FsbWpLV0RlVHlyS01wand3eFN0MWdVSEFObkk3QlFqOXlEN2dSM2pyTVBuWE5zajE3MkJESEdUcURuZXQ2SDRBMGQ0aXBnYmN5OUxBZ0FJd3VqSU1hQUJmMWdYa2ZXZ0pTUEwzaUcra2FEOVh4Q044OURhNzc0MGNWQ0FVRW5BRWRaaWFud0R1T2lYOEFFOEloZW1EcnJpSDdsSG0zbnZqRDk5SWx4ejVLZ0xrdkpmZDR0d25mTVl4eDRUeWxmRTQzQTgveE1NejRPN2RtWTBZLzArM0Y4Y1EwQnBsbWNpZFVNUFlFZm03WWtMRU56TkUzYjRnbjZTTnAxM0FPVGdKUjNOYlk4QjBDMEJvenh2SmZWcUJQdkJQNEFQcFFDSzdBQ1lVc0pTRjNIdXJKVXhxV2MyMGtBWVVEcGxBS21kQlpiRnJEQkxIUE9IclBGZkdpZEd1UXNwVzBDQ0hTa1FSQ1NCakVhWTd3RXRzU1BqR21IOGZNNU0zbnowV0xZRVZTeFRtQWF5akZ0VThLTUNTWU0zelZseVp0OHVWLzVNYVd6QnVUNnlGZ0FEL21YaEJwTlNObGhVRFFjUUlibHdyUFJFQ0FhbVQ4bVI0Z0dLSW5Oa0F4bWdpUFBIZ2UyZm9tSnhTSkdxeGlUZ0M5MWNhOTNZSTFoN1VoaWtmRCtveCtXMlJxUVZuLzNxUk82TWJObjBScytZZTJ5UkpmVTg2Qjl5azg4Z1B5RVZCaTg0N0dkbDhyTHpBWFhDSDJXbGxnZG5Bc29zUWN1dkQvNmFnUFh0YUU5aGdyZ0NRcDBuTTN6QXd4eWJ0eXpQbGw0QjMyY1QzMVpsU1F6WEdpcHNSVEV4U0l2MnFGN2xwaE9jQ3p0TkNtdUYxYVBNVjNiNGlxVW9TL2pSM3Nsd0VqOWx4THJDQUU3dDNqSUN3U04wem4xT2M5Q1g3VE16S1dsY3JkNUxqT2JBaEx5TEZaalFpY1dBeFlLL2RQWXpmZzBGbzBwd0NMOWdpVU52eG10ZVBxUHZBbSsxTzlabGRKWDBGMWYwL1lBTkJDL0swbi9wdEJvZCs4QU9DMzFINjVNeXNaeHBaMEVFSWpGSEtiRDZXU21BTkxzZEtoRXp6TUo4aHN5aldGZVp6RnRHMENnS2FZYWdUQUhhTXpZdERmWGFXc0dPd1ppWU5zd2NZd3V4OXBQWXFKanNRZ2pTSXhDZklFR1ZlNkp0c2hTRUNGSlNNUkNrWHoyK29oN3hVSGtmQUx5QUp6Y1E4c0hKR2lzenVsbjFtRGc0ckRRRThDaWZyU3JBQ0NBaWU4N0RFLzVFVEFHdm1PKzZNUnRHUGp6NURrR0pEcDUxekZsSmdidGRrd0ordkplK3I1WkxITkdZM3g0ZmdBQU9vUldFYVNqaFVqZW1QcjlqM1ZBWGx2V1ZkSGVaamJrblVlM0JTRUdMQ1YydzNHZXBUK2dZOHpSckNZUkhxa1h5dzc2QWhIeDVTZldScDI0TXZRWGJhMDhkWWhWekhQaWpwQjMzTHdMUWFOdkJRQ21uWUNFckVxS2dldFRBQnJOZndTUUxBcWVtZWg0N1dFcGIrMjJsSUJLOVl0N1lTbVBOdE9YQlhIT2t6Ym5BaHZya0R5QXoyZ0ZjeDdRb0hWNzcvREQ1TDljZXlCUXV5NGxmWWI3YVFTQnJKU3NFdG8xN3M5ODR5THRwNzIwclRHbkx5ZFdRYnV4TG1jc3lrOXJ6M1RtM0UrSjNJV1VsUzlaY0ZqZkVpUGszVWVsSXJ5RTFlVzQwczRDQ0FQT3dFeW5nZDdIdWRHUGU5emorZ0NDNG5URXM1aTJEU0FJRUpxb0FXeVE4dE1UZk15eG1SVkFBR1BZUUVGV0xXU0ZvQTI0SjhJbnJnS20zcHpMd0xjUGs5ZU9tSXpCaExsalJ0RXE1ZU5HOEV6dlR2T1F6M2tham8yR1FzdDBEbmpoMzVZSVVHRENhb1kwYnU2eHpQaVFsd0RrSXNETUhkdkdlckl1ekdkbDhOTUxGSE52NW10ekwwU3J4a0F4UWVBRURkV1pSZWNlTjdnbE1Gblh4V0dnVDdRdldxZHlNbnRBWGRRZFNMTjVycjMyU2VCaHJEUUVEdmRSM21FVSt0cG5wR1h5MkJPWTluRjd4QnlNY1d1SDVKVlA0R1FzUkpsV21ldGo4S2x6eG05Y1Bwa2F5Yy9MZFJVQnozZE4rd3dRNHZvU0U4TXNydjZ4NmloUG00NXRoRzZ4R0doVERBOXcwVWVCT0xUV1A5R0tWVWlaa3U5ckJOd0NRZWpJWlpMZ1ZSb3RnWmZFM1lJTzNBbVl2SmtvRWQ3YUh0anhqUDFTRmdvRHJxei9vZjNqbG9qMVkzNi84MmlvanpINzZ5L2FCaTNHSU1YNWZkcytaaFVRaHpCUFFKUjMwdGZRUnoyQlZiUmtOWXViQmozenRkR3h6d0NZckZQdXl3YVl4dzJWYzJrblk4bzUvZVM0NGtEUXdIdWJLYUl2N3hkVVMxYXBMMFZBVEpYNjZ6K2pCUSt3U0l3SHErZHhwcDBGRUNHYXhqQm9rMWdlREY2YlpWQVBHclM1N3pUdWRiNXRMU1FGL2RKOERPNEVKK3I0dEVZTW1RWkNhM0pPL0FIbVBlWnpQZ3c2Mm0rMFQ5ZXkwVVlNR01jR0h3YmpQMlpOd0JpVWhGV1dnTTRNQzB5VnBnME04QVBIREMvUWphQ2lMZEppYUQ2Q0lvRUJQdWdBVWhveHMrRm83VUJQNzB0SWpuV1Z4LzN1OVo2RVV0NUpZQmp0VkNLQUFCcWY4VllHcHNadG9YNjA2NWhpdlNNTjB2TTlEM0JCQi9uUk44KzJwMG5iRW1UcW5QOTViNWFWRWVpb0s0YUxacUZKYUEyRUFDY0JDemsvN2xtUWdFYm4wREZBSVhtOFA0QkVXNDdtbEd2cTRacDNDbDNSVk5BaEFUaTN1aWlESUJCYm82K3dSQkdxRXFBSXNCSWNBQk1YUXRyTzg5RFo4N1FqdWprV0xFbHdaZlUrbGloYUtzQUo0TEphNVBzZUZCUStkZlRrS2dMZTVBc1FFN2ZDelpFRURDWmdVdDcwOVFSeWlrYzRUQ0wwMGNoelk1VVJjTHRmVWxmeFJ2cXYvaVMyWjFTbTlydDNXOWRZQUl6Rk1WRUNqQXR0SGpDc0R6cldadG9QeUNkc1kxMHdodE4vZ0RzMEdjRTBLNGZ4RWxvQjhjNng1dWhUN2xVRzBFR3BPWTdFTGFzUHFsUDZpREc0bExqVThBOEFWdDJCd2R3YkpVdGZ4aFBpZmxzcTUzS2QyM2tBRVVMcGNBVFd5RVF3cW1pWXlYZTU5MHRteDlSQm9FOEM2WEp1azNzRGN4c0FBa2pUdVZsOUNDc2FHbDluQnJvT2IvRHE2TTRsZUJWaklMaVREd05QREVYTzJXTUdhVWZhaWVleEhIQkgyVndIVXBSUHdEQkxZK3lZVWtCSnlwTW56MlFLcHgycjMzamRmL1dZQzBOUjJKa3RrZnoyOGlrajArNmNJOWpuSDdkUlo4K1hYNzNReE1xT0VoOXZuc3Y2Z1BuVHdzdzRtQ2RDUlY0YUdvRWtYd1FaaGt0NEV2cDVUNEJOdndwVGRVeHJqMVZJV1FSVWFEeGFFSngzUFp2NnA1d3dNTS9VN25rZWJSRnpISUZLeW5kL3lzb2VlTEFKNkdTSkFrUlpDZ25DL1pJWk1rQ2ZlcUNsWnhBWWhKS0VtY1VhRWNITjdhU2U4dktqQXpYK1ovWUdNS1R0Y3g4dFBvblZRMTd2SUFaRjRLbG5QZTk1eit2dmRHMkxiMGhpSmZKK2NkbWh0ZmZLTzhmdGsveEwrd2pOMGFjZGE1bnBzd2NsQUl4VlZ2OGdOUFhIcGJpSmc4clp4SFZtZU1DWWdpZVlOOEljUGRGRWJFNzZIMkNZOXRDSDlBM2p4WFVXTEFBLzFpYzhYUjRicTQ3M3pWaFNybnVNSjZEVGRYdDVqUUhBNm5JbS9RT0FWeS85bGxJcjRTdk94WW8zMWttc0ZMNmgvOFppRzB2TzlkZGZmOTRTY1pqK3dNS0Q5dWpMVW90WGptc21qYzg5NnY5VEFTQWdVTm9CeGlhSXlHQmxCbVc2aE9aTmM3cmNDYlBIRkRGZjZOZktpdk5FODlybS9PeE5Bd2orZHNpWlptd0FZQkswUDZaZng2YWJZY2FtUlFKdU9ybDNIQlAzQStHalhRaFQ3UlRtb2d5Z0pJSUtzNkRKeFpTSnlXQW0wVjZoY1BmRVIrOS95dEFmY3B3OThHRWc1VGg3V25QKzIzc085OFVJTk5SbHpCTVhHZUhMN0E5QTVGNmFGKzNZTWNGTkc0c3AyaUJPd2x5WnFrTkhnNXVXUml0R0YrWnBBSlJ3eGxpVVIzc0dLT0xqai9ESG1Ka3o0L3NPRFRFd1RGV1o2SVRoS2tkK29DV2dDUURSZHBpdTZ6YUNpUERNTTV4RGM5cDB6TWcwZHU5R1M0OUFHRjA1S2N0K2J0blExbkdKN0dXaUQ2MFMzNkFjNzVrKzV6aXhNZ1NXNDFpK0FBQUp6WjIzY1RWaDVqa21ZQ0xVNWdGLzdtWDFTcG1laVk2ZU53cDUrVXc3akJtZEJ1azZkNUY3OWUvRCtOOVowZlNWZWRKUDlML1IvejNQRTNlQWZvdlhFRHJhMjdzZFJOdDVXWHNkNjR1bUNMT1dlVGRqZjcvRVNoUTY2eHNKRXM2NWpHTThFcThPdmVRRmdMZzZqWDNnVHNxc29yalpzczg0QmU1c2FPOForcVk2NW5uNHp1Vkt3Q3IrcTA4Q0EzaWlldVE3RzhBd2VwQmRZM0xlTzdDTUdwLzZXeEtsUVRsb28wOVJ5UFpLZ0NPK2h2OENIaXdhNFgzY0k1dEtwd0pBWUxaTVliU0plYkxpSU9aK09WMFpXVGRBUXh0RUdMT0JiQ25hTWUwU2dPQ0h3NUNDcUEyRzBmOG1FaHhqcGVVSHNPbndmUFZqaW1tT3RZQUpUdkJoQkF1TmxMYm9Qa0lwak4yekl1Z0lOY2ZhMVo1bU1RSVE1OVFSczQrNTBEbWJmaEJ6YWM1aFlvU2ZRWnZuR1dpWVRmSW9IeU1nVEduTU1mMWpmTTVsYWlTaFRkc0JaSE12MzZWM2NSNmo4enphMUR6Uk5BRVhnQW5EU2QzUE5mZGNCRGlmYUpLQVRRRjNucVBlQkhGY0J0eEhucVAvWVVEQW1uenVzWGMrUUNHMGl6VWg5ZlpPeVpOQVRUUkNXKzNsM2JtUUF1SXdRK0RRL2ZxSjU0ZE96Z0dUTkVEbjlSUDNPNDlXQjYzUk1tcVlwdVpKeG5OaWI1UVRHdmtQRktpekZIZUw4elpnVEYwRVN5YWdWOXZtT3lUOXB0a1BDdytoeWFJQThNK24xQUVlMmtEc1JkcEFYK04yc2hnYXBzOFNjbEJDeTJpcDg3d0F5dnk1eWNOeUE0eXg2TTJUOWhMemNhbUpRTkkvOVhkV3djU243S2ZWNjN0bzdoNTc5NGdkeVZoMmpnQ3kxMzlqN1FzLzBQZTVaaWdOZUx4OHB0cU9sclNVN1ZwNGcvOW1nNmt6UWV6WTVybHp0OHFsMG1YcC9xenRBdFNwSC80UFZBWXNrdytTZnJlMDdvZitxYjU0QnRDbXI3T2NPZ2RRUlprWlhXaGpQZHlqTHhqdjgrU2M4YjhwZVhncUFJVGdtTDJJYWZsZWhEL293emR6UWwvS3NjWWJCNVlHSllEVlkrekF1d0lndUVIVUhTT253Um1vK2NnU1FaMUVjTkVhckFJcE1aM0YvSlk4OWxuaGtZQ2liUkFxdEZZYWcrZGdHUGJ6TFVLT0lITk51Nk9oNExNd3RQazlZVEFHc0dzWWZUVGxBQWJQejMvNUhRZEFFSUtZczN1ZEo3VHpmT2VBQW1WblVCTXd5UThneVdOdEFYMkFzQVlNV0NVa0dqS05NL2Q2aDVHaEFHT2VqNkdLanhnVGdaYVpFdmEwTTBsOFJkN1R1MkJhU3d6WHRieXovT01XbWptSGlha0R2eklHVEt2SmZiRUNaTXFqdkdNN2pFSmRXY3BsSVVHSGZBakplWFFpbklFN3RDTXN4ZGdRSG9DbTUyc3p4MGx4RHhEZTJrRHdiZWloZnU0QkZtaXBCTG0raUxiNm5QWURQTzI1MXpEVW82YXN1YUZ2MkpqZUEweThQeURobmJpN0Rrb0EySktsMG4zNk9VdlZVZ0tTZ0ZkOWJKNzBNVFJZdWpiUHU5OXhySFRubWxCUHlrcXhBUGhTUXRleFh5bkQrQ0c4QWhKY1Z6L3R5eTJaL3FNdkFRQ2p3cUpkTTFaU2Jsd2RPVjZ5UExyUHpCbDhURC9Cay9RSC9WRGJHT3VBclBhajlRdmd2WlJFQVVxTWgzb1Jza0MxOTR4bEVGRFVOMWlwTTk3MGY1WkxLUllMN3hPbFI1OU4zcnd2cTgwOG9adDdBcmJINjY0WngzajVKdEtwQUJBQzZUVEcwbXdMd2t3alhjNmtRODZ0RFo3UFYyemd4Qis2Q3dDQ21Zd0dDeHl3TE5ET0NUYkJkaGd5SnF4VFNwaXhqcDFwUlZlM0tiWnp3U2NmTUpjQmdCNUFDYTFVeDJiQ2Q4MUFpZWFjUVFOOFdXWTRUQVN5Snp4MFlua0k4Z2d0ZVptOW8yR2pOYUVVOEVEYkNiUHlQQm94QVVUd3BHN3lRdXlZVk03WmgvblIwbGxRY2swUW9qcTdUbU9RbUN5Wit5Vk1ITU55alZuWmZjcm43bUdwRUd6cEhDdU54SHpPTEs1Tyt2Qm9pZzZvOHl6MXdIeU5nOVFsRnBNY1o4YUdjZUpjckF1RVFQei96bU8yTWZISFRlSjhoTFAvZ0J4UVJPTUdocHpMYkl0UjQzTmV1MmdmLzdNUkRwaXB1cVF0K1l2RmY1ZzlFazNOdXh2VHByQ20zdkpaODBWWitpWlhZYXdaQUNpL2Npd2hnSTFZRU85T0MrY0NzTUlvRFkrUUlGeVpqTlh2cUNrQ3pudHpuU1RnVi8zUUtWTlZIWE5qZUIvdHpaV0VSNHptWlB3QitKaW5yREV4LzBoVzhua0gxb0dsUkZpanowSHhKVXYzNWx6Y1Iwc3VIdlRVQjVlRVZZQzJ2bU9zVXFyUXdiZ2paUDJQTzFUZjlwNGpiOGo0anpCT2VlNnpLVlBmQUo2NUozTStmZHU0aWRza0sxc21IeXVCT29zVHlYM29pNWFPYWZyS0JuUzVJeWdwaDBrc1crNG4yTU5ySEFPeitrYmVKZjNaTlR4UHY4ZzQ4V3k4UXB1NkhnRGh2N1lVSStGL3R2a0h3N3dYR3V5VjBHMUpWdTZWZjcvejZveFBuZVEwSFZRNVRJZUEwR0VNUUFNVWc4V2NFWnlXcHhOa0U2eTB6YVFEUUxwTENVTWhMQVhTbkhRQW9STURBQVlDSUJZZkpKUWV4Z2xabzMrK1loaExFSWFsWThkcTREK2dBZjNyK015YjNCNEFBSjk2R0FyQjdua1pOQmxvTkh0Z3dMTFVoSkpnTjhJWTgySVI4WndJRW91SE1Zdnpmd0lsOG5pT2Z1SFpMRVQ4elhtR2N3U3cvUWdnbElmQkVXZ1ozUEprSTRUeVg1MjlNd2JoUHE0SVNWeUQ1eVNoSFVIamZZQXhDU0RqNnNKRVdXY3dXSUpSM1FscG1rZWVRd2dSdEJIWXp0T3VhT2ZKWTZVK0RDVEFpemFqWGNSUkVONDU3MWw4c05vaDk5cHJnOFJLZUhmNUFjYmNSM3RUaDRBemdseFFIQm9DUWNhYmNqekxPd0JneGdUZmRKaTcyUlJoc0hPQWo2NW9DSndRZ0FTWE1jTzE0NW5pVHdnamZuTmFvMmV4WUFFbC9udWVQb2x1Z0k2K3FmMzFWYUNJNVNRZ0NkMk13OE1LV0dPQ29PRWlDUWcwQXdNOVBCdU52S04zQ3BoMW5oVkVuMUFIMWlOMWlFQUZpS1NVNXgxWkZkRFZUQmYzNzdjSUVvR0J6bGtFcXhkMnc0L1pHSVRYUVNaclk1UHdGb2c1ejh0cUJGZ3UwVWk3RzN0eklSS1FwKzdlTS8ySlFOZW4wdmF1NjRmZWdXbGZXYVBGRE1BTWI1QTNHOXFLQjBvZnpDd3MxN1dCTVJUQVFlbGdEUW13ekdKMVp1bkpEeHdZSC9xdDl3ZnExTTl6QVl5TUxXMHdwODFJNjN5WGhNdlNPNmdEM3VZWmVJQzY2cStwbC9QdUdSTWxTRDR1TDRCWG5tenFqMzg0Vm5kMFJTK3V2REZwSjVZTE1tYWU5Q3RqUzJENkp0S3BBQkFHR2JSNjJJMm10czBrMEZBSHBPbk1mWm9HYXZ5QWtDQkJzcTJrMHdKU1IwMUFrTUdvMHlmWUo1MGFVQXRUSUtERHlIVk16TlhnWTY3VGtRa1NURlZuNStlbEpSSnEyaXNhQXFiS2RSRWhaWkR3Wlh0dTNBbWVvL05uUU5rVExQelh3S0x5blZNdWhncGdPTWI4N0pVOU1uWG5XQU5HQWUyY09pbkRmeHRCbjRIclhYSStlNExMTXpBbTUyZzVCQWpoVCtCakdCSlE0THIzQjR4Y0kxaThrL29xZzZzTDQ1RVB6ZERRK2REUmYzVURtcUxOZUMvMWNrMDVxU1BUTWt0TVlqUzhWMmlDbHZKN0RxRm1UMVBIcElBb2dYdm83M3cyOTdBS2VCNWFwNjFZbXBqZTFVbkt1Zzd1aThuV2VHQUJ3aHkxV2NvazJORnBUSmc5a09CZWxwUUFSZmN3TlFNT01hbW5IUFhsSnZBYzlkSW02QVN3eHlxZ3ZDUXV1SUJGZGRJSGxnUnc4dHRqMm1oQ3FLbTM5a0VUNVV1eEFCa0xLVnVmanB0RFhlUC83amUwSDRCTFdiRkVZUDZFaUdjb2cyVnFyeWwvS2NQZUZFZnZQQW9HRmhiUDNBOTh1SmZiUzE5Q1UzM0JmdFJxOVd2dk9aOW02MTVmczBYenVZc1lmMGpicTRQM1MweEEyaXg3OVBjL2JaZnoraGpBSnJIYTVyeTk4VVdMenIzanRmeFAvM1NjLy9xOGVrajRzRFpFdDF3M2Z1U25PT0Fwd0t5MmlORFhUd0M5cFdScUw1RExNcHM2b0lIMnpiRjllQWtnYnF5UENpMEJqMit6K0NhQTF6M0d0SGVsMEFFMDZzTnk0Ynp5NWluZi84bFMrSzZ6eGltTHBXdFQ2VlFBaUUwUlk1UGxZSElHZ0trNDgyU1FRNmthODZRQ0NKcXpRWVhwaTJ0UTN5VENRdDExYU15ZFJnRVkwTUlTOEdZMlROQTZhNEg4OG1SQkZFS0UxdUJhWWdVSVNma0lWOHlFNlZTS0FIRE5GdWJzZjB5Z0FnekRUTlNieGh1bUlGK0F4M2d1NVdHT0dJZjJpbERXTHFPV3YzUmZCSDN1VVo1OEdFQ0V1SE1BQlUwa0ROV2dWbGZQcE5tako2RVRiY1U5NkNTZi8zRS9ZSDQyZ1hvMnowSm5nbHMrNVNld2tLQm50dFUybmk4djVpYWY5MVVPVXlodzVKeTZzTmd3eFllT3pydXVMVmdsd3BRd1JMVENmSlVqbjgwTUFKcGtqZ1BNd2pDZFJ4dDdaV1ptQ2N2UW1BREdMSFlWc3prZzZabnVUVnY2NzczUVA5cThjL29IY0paVk1Ga1k5R0hQVkYrZ1JENTFNVFVUeUlwWitOemc0eC9yNUx4N0NOdWtCTEVTdUJLcmdqcEtNWTFubW5ZK3paM2pudW1HSDIyR0ZwZVNDTnFZNlZrNnRKRjJabTFic2h6a1dWYnI5VjdqaklyTVlsQ2VQbW1QZHRxVFVFVnJZeVBUV2IxejNKaks5VjhiQWVmcW9uemJPQ2JTbHJtbWpaUTc5aWVBMTNtQ1h0QjB4cys4ckZocFVsYjJ3QkJCbkdlSlAvSWVyRjlBcTN3WnU5eDQ2WnNCMU1hbVBBbkk1WEtLd2hQQUZ6cmFjMmV5ZmhrL2VRL2p5dWJkOWRYVXpYL3VFUXFFV1VMR2p2Y0grclViNEFzb1VPTHdReUJuVE03SE1vTnZMcVVBZVdVQ3BlcWVMODB1NVQvS3VRSVFSNkhhSWUraEZlM2x0MVNFV0lGTVVUcGtrVDBiZ2FLekg3VHByRm1EWVozeTVlV1BwTGxLK2NxZ0RrdDdwaldGR1REZjBxcGlvVEJnRGZveGNSMFpWQWFHZ1JNQkVQOHdLNDFCYXFCZy9nWlQvUElHTFFZZDRVb2J5Q0JVWml3RkVYcU9NVHAxa0M5QUxmZWszbzZoZVBtNVptaE1CS3o4Z0kxNllsd1o5QkdHS2NkZVdUVFpUQnQwenJzeHZZK1dEcWJSdkd0TXZjeks4a3FlSGN0QWZMUjVEcisrUkR2R1FBVVBZZ1lDNmpLalJYMnZiYkVCYUljaGVqWW1DQVQ1SC9kTWFNZGR3Z1hGeDhzOExVNGo5ZFZHckVGaHVxa1hrN1RQSTRmSnBuNmhUNDY5bC8vTzA1YjBJM1ZMWkhrc1ZkdzJtQ0lhMHJyR3hNMmdIbWhPOHdSaUpYMHN6OGx6bFpGejl1cExPTkRPOUY4Z3dqTUFLbWJoQkRQTGEvRW94OEMrQkl5aDdWS2lMV0xJWTZMSm9rZjZsSHU5bi82cmZLQWhTVjIwVHpUcW5MYzNtMG1ickpzOG4wdFFIQXVYRGZxZ0M2Rk5tQUZoNkVpb2paYUpQQWQvVWs4V0R1T05xNGZiSkpZVUZsTENPZkUyOHVxenJCMGpZR1A1OGZ3a0dyVjNWUmQ5N01vaG1OSVlWNDR0TTQzOER4aG5XY2gxZTJQRGUwU0xIKzl4M1ppTmRXQzh6MzhDMDcwVUYrTThmU2I1QXFnZEUrU0VNbGVHOFpKNnhscmgzUUI5NDhaOWhQK1k0ZzVSMXZ3ZG5ETWV3MFBDcy9EVEFINTlYanZpT2ZMaklkNGRlTXRZVklZeFQ2SEtOR3I5aXZ0T29yQnh4MmhMVTcyMU9RVk5ZS2J4Qm93djliL3hQZGI5ZjZvQUJPMVhJQnVHT04vV0pjeW04dS9YWUxTUkpZM2tvR2REK0RTOWd6WkNsVm50S0lrMWdZWVp4b09wc0Jvb015Wm9ER2JVUER5SEFCeGRSTXluQmdSZnREMXRtZERDZERBTmV3eU91VlVuejJEQlZNVXlHQ0R1R3pjV0M0SVNvNlpSWk1BcUx4WU8rU1BZb3dWRmtLWXM3d2VjaEZrQWU2UDVNZmxvcVA2bkhQbWp6VWJUU0Y2QlR3WVZHaEVzSTlPNnZzM0hUc0tvM0JNRzRqeEI2NXd5Q1NLYUJZYWV4TzNqWElKd25RZThDR2ZnWUY0WFpSa1A5clFjZFJIa1JjaGlSaGlyL2tsREhldUpMZ1JQeXFPSlNZQVFkNFh5Yk53SmdBZWg0dm5Lc0lWUnlrTlRUWXEyaHk3NmtYSWpmQW56Skl6VHZkb3pzUXFFWE1CQytnamhCUENwcS95WUxXMVAyWW5SQVNEVWlRWXJNY2V6c25nR2tNbVNvejlKM0hQcVBrLzZPSUU0Nyt2eWlRM3liSnE1dmhvZzVsd3NhQlFGeDhiR1VnTDBnTE4xa25iVnh3Q2I5SE50U3NET2szYk8rNC9YeEVmb1o4WVB3V1VjcXFlTnV3MWdsZlJiNS9RSC9jODk2T0ZZKzBXYlo4V1JNdVlENHQyN0YvQjAvd2dBak44STJOVEZQbGFRc1orTzE4Zi9zUkpvUzJESHRYSFdqMlB2WUIrZzQ3OXhKVFlyenpER3g2Uy9HYTljVW5IWHVaN0FUK05BZWNwS3YvVS9tL0xTaDNQT1hqMEQxSE0rWTI4czB6VThDSTIwZGZKNlBqNE4xQUZhMmpKODB4NTRkczQ0OFp5UnA0enZkNVQvcHdaQVlLNWhKQ0hzdUQ4S2NTN2xIZ1BRd05RQmRuRWhLWUlGWTlOaGFSZG9HU2JrUHkzVlhxZU5xd0s5Q0lVRTcyQzRPckFvYkFNV0U4SE0rTGNsZ1ViV1JJQ2cwY3NnbDUvcFU5blJtUDIzR2RnME5mOE5DQU9Kd0FBY0RWek1Pd0pKSG9LUXNNRmtEV2dJSEtPT3RpTlBCcXJCVFdNMHdEUDQxZGt6UFlOR3A2NFJUQUZSbm9IeHlqcyttNW1jRnFGUDJnSnlBQ1dKWU9XTFZBZjM2aWZxZ25reXR6c1BvSWtLVDRycGZiNmFIT0FsUDBDSmZxRkYzZzlUQVRLVWI3RXYxaHphT0VhclRSSmpFb0JGMEtPSGVucy81V0NzWEJFUmtHakN4YUtOdGE5M2o1QUF5dFFsV3BKM3N5bkhOcDk2aHBicXBoN1JOSUVBZVpXbHovaXZYaXd5Nm9VcG9oWGhnMDdheWVhYXZOcFF2MERiMUprYmdwQndEY01ORUVtYjBOYVcvTW5lVVRrMDlxVkUwTHF1VHVpUTUza2ZkUitaUFlBNnBxeXdPTVljak5lWC9tZHhKQnB4RXBlTjl4YVhORThzQXVvNEtqT3hQbWl6TVFIQTJvcEdiWThlNkV4ZzB1WUo4cmdVQVJEOXlwalMzcDRQR0FQWTd0V0huRnZheHY0QWZIbEcxbnFRSDgzMEFXMDZ2eDlnQ1c4SXJlZDU1c2ZwRjRBalM1Rnk5UzM1d2dQa3lmTVNQQjdhaVArUWw1V0FGV0MwTHJGQ0trTi9vaEFtZGtpL3pKaHdMOER0UGRPM3h6cnFQNDcxbndSN1p6d0NiZU05NFRPZUNUQ3lDanZuZWRyWUdBOFBWYWFnYXNrMTR4WVAyOCt0bFhjK3pQNVVBQWdEU3VPYm1pT3doa2wwdmgyR0dKdkt3NlN2NFpqdUNEd05xN0huVXpzaGRFSjZXMG5udlpRZ1Nrd0dFeUNRQ0FOK1dqRUhRSVdrUXhvc0l5UGpZek10MHpYbWJBT2M4SW1RUXBkb3RFQUk1cU9EUjVQTE5FNUNTWnN5RnhxWUJncmh6dXBnQUdOc2hLWHk0aDVRVjNrSnFGd3phR09DNVFaZ21jb0FOR2hwMVFseXcvaG93aGhqeWpYZzhvVkdUQVFqQm5nTWFNL0w3QlB0aTdtT2ExZ3dpUU12aEVoTSs4NUpCRGc2ZUE2YU1UdlNWTU4wbVZSZDR4TGlzbEsyWXpNbXZBTkJ5cnJFL2VOOGdxV1VtZjRuL2dIZENTMzFrSStaRm5oeEx5WkM4TVRrN3JyeGd3Rmg0UElHS0xtR3B0NFRrMDNjaGJaTExJRDhCRHFhSjNGOXNESWwzaUV6VDNJOWV3eFp3SnJ5YWU0WUU4YW9iUFhsRHdabTBBb1RWaDhDMjE0ZDdHMEVFK0RtM2JTMy9tQ1dTclJpb0UzYmllbVFmN1FLc1V5ZzkxSUM2a3habkNlV05YMGNXTkdQc3NZSnZ6UFhpSHFyQXd0S3JsM2RyRGhvRXUwNGxvcDUyWHNkRTZCenl5THdBMkRxcjBzTGM2bmpDSUNNU2UxSkl6VTlHeUFINkZsc1lrRWl1UFJuWTIwOHAzMjFsU1JlZ2h0SUFqRFFWRDI4YjhaWndFS0VjMkpUNHRhU0QxK1JDRDU5UURub1pxOHZPcGZ6emtXNEJuQWFsNk1GWlJTNHNTQzZqL3NWSFl4MU5NQWo4Um45SEo5bUpSckx3Wi9jb3k2VVZHQUhqU2xPbVVFQndMdWZZaUl2ZW5nbnRFczhTZDVGTzNobWpqM1QyT2RxQnY3MGUvUXlqcjF2bEFuOFlMUlNvRDllRlF1ajhpU3hZTjdUV0FTVzFObXhOdUZLQmd6Um1tdHFFK2xVQUFpRENaTStLZWswTFNTRkVldDhCZ3hoYmpDT0ZnY01mUVJHdERrREJDTUFQREJTQWwwbnhxUjBZQU5ENXlac21KUU5JdGNOTm9rdjEzOU1nRmswZzlBTUFmbVluQTE2L3hQamdEa1JzZ1lvb1drQWo1cWZ2QUJBTkJmQUFYaHpubUJnMWpPd01Iem5QSXRnTlVBY0UwQkFFY0h0Mk9aOTdMMnZQZG9RWnVwQ3V5ZU0vRmNYdmttYUx5YWduRXo3UXlObFN5dzlBSVI3RXR5SWZtaXZmQ0FMZUNOc0FaR0FpdEUwemlSUDBHS3dHQVpobXhSdzRoeTZhOGNFYUtvSHBrVWd1aDRYaS9PZWJmTnNlK1Y3UDh3NzlIUWVTTkpYdEJ1bW1tajFhS3dzUm9EVFV0TEdZamtJTlFtSVVTYmdpTG1tclp5enNhSklZa0cwVXl3bG1MaGdUMWFEZ0xrRUNOcGowZ2srMHc5WklnZ1V6MVl1VFhvcFpYMEFRQ2phVzZ3SFFPU1ltSlFKWlcxbkFhNnNpeUtQYjJhd3RMa0d6SWdSV1RjUllJa0x5YjNxamU1TDFrNzAxMWFwdDN2NDNJR3p1SlVBQk8wVCt0cnJCN1IxNDBJZmRnN29EaUFRZ0tsUEFOajV2Z05nYVd4clQzbXpwUHZZanhKajQxcktqVklTYXhPTG5ldjZtWEdzWHh1VHhqM3dGWjZoVGhsalk5MEoxRXdIalN2RnVERytqYi9NaUFvd29weU13R0VzUzc4R1VOUWxnai9XQy8wNVFlRHFnVjhGa0hzMy9FTS84LzRaZjQ2Vjd4M1JpTEFIeW95WldBN3dzVmc1OEYzNVJsY1BVQncrakU3eXE0dHl0WVh4d1ZxaWJIWFdsckdzQW9UR3hpYlNxUUFRMExkT25XalpUUkRtVXNvZ3dFYWhtckl3REFNZ1B1eVRib0ZJdlhWa25VNG5OUkFNNUpoY0NlSnJtKzkrVEJpeUFhZE5NdURDS0FnN3FOcDFuVDFBWUI1RVJvdVN4MkNYdEcyRXVZSHFYbVZqUEFhWFl3S0xtOEovV3dacWpyT1BkVUlVdVNBcEpqM3ZwcjdxcWJ5QUFzekxZQ1IwTU9nOFcxbWU3NWlRUzluWmgyR3FRMENEZ0ZOTUJDTTM5WlNGZ05ickhnT2NGa080eEtxUnNqd2pqSTZKbVdZT0lCQ2FvUitOQXEzQ0xFTVRkWlppVmszOTNlZS8rbmx2UUNEWG9sbk42NEUyNnBsNm9abDdDR1ZXZ3B3WFN3S0FlTGI4Nms3STBONzJtbTFndHBMeGdZa3pBeXRMR2RyWGM5S1BuRWRQOWFmeFN0SGs4Kzd5dWdjempudG4xTDdSWHpub3JZNW9wUjMyQzNqMkhLNEFmVjkrN1V2WVpTeTdmcmtTNFhXdXVXUG1pV0RXdjRBVUNYQUpXRUl2LzFtY0pMUU93S1lCQTQvZWE2UXpTMS9pTjlLMjl2cksyT2YxQVgwRFNDRUlzeHFxc2dDYjlNWDB3UWhmWlJuajRRMFpmNDRKVjdGUzhnQlpDYUFGMnJXRDh3U2kvdUYvTm5WaGtWUld6dW5qbnNrYWhqN2haUkhveVdlUFR0b1d6eE93UFBaMzF6MmZaY3YveEZYb0U0NHpmdkkrem8yYjg3bVdlM1BkTTQzbk1VWUNUMlFCa1lmQ1lZeDRSbmhMQXF6SkdpQVBlSFEvZW5zT0s0dDdIZWRjRkFPejFEYVJUZ1dBUUFqbUtJd0ZBbVN5RnZBeWJwc2cxbUhMT0MwTFNYbGZ3a1FuaEw0bFFpb01JZ004VEtsbnVPR0hvR1BHZEM5dHpENmF0UDg2T0VhRWdiUFkwQXdnNWlTZ1VIdGlWQVpibUdMOHZ3WUg3UTdqeHlBc2FDTjVoblpubXZhY01JbnNjNDY1T2NrNzBVUmo1Zzg0aW9icEhnT1RCa0Q3czlHMGFMc1pwTTdKTjk4SUtjSXJEQkFEb05VUmVvQ1VGTk92dnV0ZE1UamxzQTR3alh1Zi85ZmVuUURKc2xUbEEwKzJ2NEFpaXlLTG9JQ2lBaElpaXlpaFBqQmNBRkVCRFNJRVVSWUJKVmdNUVRCUU5rSEJCUkJrVTFDZUt4SnFLQW9xS0Q3WkJFUUJEUVJCWlZORVZJSmROcVgvK2F2SE4rVDA3YmxUUFhmbVR2ZmNreEV6VlYyZGxaWDVWZVk1M3psNU1odWVyc1h5b293SlJKWW9RUTJEQ0ljSUdOZmNBMnNDSk42Q0xPOHlYYVR0NmdmTDFOMDVaUlFGNHpxQnpPTVJqSkpYMlZ6ZEZEYU1ZalVwbHhkQXZFWXNYNTRXR0xLb1RDRm9senk4VnNwaktXc242M3ljQmxFL3lrLzdZbFdhbzNZUC9HR3NIM2dmL2hBUTcxTWRwSkFiWklJUWhxSG5zK0FvT084bWVlVjNyN3JwbDZaSnRJa1h6ZFJXOE5LdThSNzNuYTBFUHhib2NrSlE4MTR5UFVBQjZtdnFtbWtjVTQ1WnZrbHVtdUxTN3dRSXhxT25ITk9JamxHTUtYczh3ajc5RHZhK00zYVJEK2Y2aER5NVIxM0dQdXc2ZzRzbk0za2M4MHdlRXZsRENOU1BaODg3SVpPTUQzMEZBWEpmU0lwbmFoT0ZqeXdaSTRsZmtzL1kwMi96VElwUW9ERVBvbjdPZ0ZBdi9RdjVRQ3g0S2ZQT2pUdDVvdUJUem41SEpFdWQwcjdraDFQR2VLNGhVY2FMc2M0N0ZCbUdkUEdJZVQ0REtBYTArM2gvSlAwMzQxLy9OOVlSNmt6ZEdhOUl5Wm1tRTBFZ0FKRTUyWUMvZkR4VG9OYTVuK0wwc2czaWJkNUlTcHNKRVZaajNGOFVieUwvWVd4ZWQxVWk1SkFEcmtLSnNrUHM0akwxblE1dVlGSkNXVGRQd0pnVFZuYUVZS3dkZzlWZ29DRFZ5VW9OSklZd1lKVkx2QXZJaEFFWmkxUXNpanp4S25nM2hBRkY0ZjFvRS9MaW1Wa1NOUlhXLzcyMVczb3d5T0F6WFVib1pqQzd4N01jRTR1aFBUNFRFZ1NidVhCdEpZd0lFSFUxZ0gzUG1wRUljUXBBbTJCQ2NWRndQRGJtdkVmRlRZQWtSb0oxeG8zdmVmNjBFVDd4V09RNkRMa3o0ZTZhRlM3TEtmaXdaTGhGdFVjOTVWZFh6NlNBdGNFMStiUUx6dDRIMXltaHQxZGlxWVdVbUpiSXViSzhXMGw3ZkZaZnF5Sk0vWWlwY1EyUjRMNkdQUUdKbUpwNmVIaVBLUkQveEdKVGwxVko3SWdnWUFGcWxyanRsWkFkMk1XVm5CVUd5S3c2cEovdGRmOWhYZWNOb2VqRnBDQlpZMEo2MUlWaXMrSUpnVGNONXhyTTlHZjFwYWdTMEp6N2tYK2VMd28rL2RSOTNPN0IyV2QvbzB0Zkh4KzlFOG5qbU9rZjV4UzhmcUovSlkvKzdNL245RCtlUzUrVmlRaXdwbE9mSEhQL2VQU09mVVlrRTJ4SU5sSCsyYWNFTWVCZGhKdThuaDFaa2o2SFRMcXVMeUh1ZWFZK0w3NGdKTjUxUklJQ1gwN0d0bjV2RFBDRUlDck9rUjFreWpqMS9HV3lZQnAzSkZYS3laU2wvSW50Y1o2L3lKaDhObjRvYisyVVBOZDMzanR5U0VZbEwyS0NZQ05kcmhtM2NEQzJ6alNkQ0FJQk1DK0pJTVVNZFp6bHZ6TUZhdDM3dDMwaktlMWxHZXBvU2ViTkRDUUtsWHZQNEY5ZUVaQzhFU0FKUUhTZDhqZG9NN0Fpb0NoV2dWVnhYZXZrckgvSlZBYUxuYkIwbllJWTE1ekxFMnRIUUJGRmE1VkhQQUtzaVNRRFUxa1pXSjdQRGMzOWwydHgzK2NlUjBLQ0FKTGkwcVh3RVpBUUNSWStQREI5QWtsNWxDKzNKSVVleTBpa2VWS0VnblluSlNhQllDQWtZWlBvZFBFRkJBVUZaLzZhTWlNd250V25rQ0lBWTZtbFBUbm1lKytReFliSWpXdmNQWitnSlBoZ2x2blp1TUNWZ3d5T2U0Q2tiRWNFZ0lVdS82cVVPQmpmcVR2Qzc1MGlMZkNQWmVkN1JJb1MwRTZFa01YSmJTMXBjeXhZaENJcE1SUHJCaVRtZmtkMVlLVkdVWTdUa0N6QkJQcUtIem1xUkc1UnJqd0hTSXozNzN6WldrU0FlWW5Nenh1UHhrLzJHQ0VEOWJ1OWtyRmhlaXBLM2J2V3I4alFYQnZmYmNpVGE2TXlWQy8zK1dQNStsNy84M204My9tcWN0VTlZeURqQ0lHUEIyMHNneFh1ZmVnelNLenZHR3I2SkNYbXMyazk5VUFzZVpWQ2Z1TWhKWGQ4VDZZWkQ4WS9neURQMFJlTnNVeEo1SHJxcm84bElacnl4eHRyU3BLQ1JwRElBczhheCtLSWlmS01zWlR2dTVCMzA0RndqWXhNSHU4Z25zTmMwMC9KYU1hUmE0alkrQnp2aWtHVy9QcUVjeDRqM3lYd09tMDZ5UEZFRUFqV0NKYTFhWW1BTzkyOEttVmsvdkdva2s1NUpxc3cxTjBnMnlzWkxIc1JDQjRISFZxSHBhUUZRYVVqcHdOVHdISHRHOUFFSDh1QTBGeVZEQ0N1emxYSkZJZnlDY05ZT1hIbnlZL1ErVjU5VXcvSExBbUxZT1RHVFhCU25pTklpa2RGOG54bEpWRzRGTEt5S0JuS3plQW44SlJKdVB1T3hSRnZUTzVWbHloMkZrd0d1UHRZUU1FRTZlR2hJZmg4WnhjODc1WVFHM0VsUEZnYW5wZjI4R0RrR2E2ejdGazg0am9FVEk1SjlEamhwa3pqaVhDWGYzeUdNdng1bHZjMEVnelhrU2Y1Q1JiN0V5Q1FoS0k2SUhCY3hBbXU5R3p2bjhEMDdxWHMweUEvU3htaFNxSkVQY09ZU1hRNVZ6N0JyYTZuKzBudWxIRzZvem9RK2dnb2dqeW1yTUNoY0V5eEhFVkNZSkFtZU1BbEtWTUVxMVpYSk05NDVOYlhCL2RLc05JZXp3bFpnbXU4UU03ek55cWtLTVR4SHZrb2FtUWducW5jcXcvS0c4TG5mZnFPZ28xbkIxbHdyK3NaSzg1dDdvWTRJNUlwendvRGZjcU9uOG9ZVi9Sa3FsVmVKRkRmOUZ6akpzbjRpY2NQU1VOV2tPWk0zK2x6K2xQYXFheVFtWkNJckQ3Umw0MGplYlNSWVJXanhiVnh6SkVMcm8xL0tVKytHRG5HdFR6TG5pRFh5QVk0UjQ2NTVsNzRHS00rYXlzQ2lnVDVQUDdGMnhCNTY3M0tlNmJwUkJBSXkxa0lWTzYrU3A5RzRFd0pCRVdxTTJZNzRVK1h2SmpjWkRyUGFEbU8zOGNWakxWenhmSU9HWmdHTjFaTWlDVXB3eUNrWUZsVmV3ay9Bb1RpMkN1eHFIayt6dXRURmdhUGdhanVtVi9sdWVEMlpPMVk2aGZQQlhKQUtCSGU3aU40eHNGRjBMTHlKZlBpNmdFYnJuQ0tud0l6aUNsNjVYSXhSNkI1bG9HL2JPMHJTN3RaRm1Oc0NNRTJ1amNKTU1wTXNGN204cEVjZVZqeTZrdFFFMGdoSUs1NXZqenU5ZGw3OUpuUTlCbTVjMjdKSjJ0V0dxY0JXZHZqbkxGbDBZUWtKWkdwR3VXNE52NGlxV3U4QkR3b2laRkJScnhmcnZVOFkxU0dTQTRCbHloeXExbHlyL0s0eEJGaC9XZmNEUkpKTmZYazl4ajJJckpUdzJiK00vV0ZET29MU005eU1wNzBKOHJ2S0ZKK2FHN1ZtREozUFJMWDB6M2YvVENsR0huUGpMK1FZb1NNcFM1UFBHVXdSdkxGREJpWFBrZnBPdzhaZGI3OFI1RzdGZzlDdnVjNWVuaWZXa3A1eUFHbGhZeVRHNVF0clBYSnhHYTRGL25ucmROVy9ZeTczWFhLVWgvbXliSzZLTk1teGh4Q2FYcEtQdjNXTytKMVFEWkcyWVdJdVZkQ2xubmpUT3VsenVtYlBsdmxsR21za1F6NEx0NUV4RURmRDJuWFA3UXhwQ3YzNlV0NWh1L2lHY2sxUjNMRUZ0dmt6SWczak1iOENIczhEcDdQQ0NVL2pDOHJYK0twdXFESGdJVUlLYy9ZZ2xPVzBJcUhPZ3hQMm9rZ0VOaTBqcVN6VWhwWW9vNHkvcDF1d0ozVTc4NlVRTURGQU5UQlIyczFhNDI1OFUrWGRGajNHaGdJQlNXWGdVK2dKTVd5WkhXWWk5VzVWeVVEMFlDZGszZ2lQSnVGUVJpSTJ4aVZVdGJreCtvaVVHTnB1MWRnbzZrRmdwV1FWSCtKKzlROHJFRkxvRkhtbnBNLzg3Qlowa1p4SWtNVSs3SW5Tbmx4KytaZVI0TTYrUHBNV0dsRFhKN0lqdXVFQWkrRkkyV1J2STRVSERJVXk4UTFnb2FRTjErTUVMbm0vbGg0Q1o0VEswREpJREtwbjJlWUp2VCtJcFRjcjEwc01YbFpkNjU1cjdDanNMaUNDVHo5MERQTnowdElsckxsb2ZpVmo0eTVmMXpXS0RoTWYxRnZSTWorRjBlWjlFTUtUUHNKNlRFeFVsaTFZbFFvODZOSXl1YWhXWldNSmYxelRrTFUyamovSXdBQVFBQkpSRUZVNG9XREcreTl1L1NyekpzajAvSlJVTnFHekZLNkdSdmV4L2lYTXNkcnpxTXdjejE5Q25sQnhMM2Y1S0d3alp1TWNRb3k3MTRlZityS3VqZDJVbWFPK3BkN2VTMlFZQVRFZC9vVW9qUW1zZ1NtU1ZtS1M4NGcvZDV6bGhnclI5djllYjV4cjF6alNGOHdmY0k3b1MzK2VQQVFYVEl3ZFJ0SlY2NHRIeE5iTVY0M2p1Z3M3emRqMmZjSUFoeU1rM2p4akQ5MUkxdU1aZm5KSisxSm1aRTFtWHBDY0JoZTZwL3BHV1J4TGlFTmZxdU9KNEpBV01KbWtKenViMVhqVC9xMXd5QVFNREk5WU5DeVBrMXBVR3FzcFZXSk5jaHlaVGtqZEdJU0tCZXVmb3pjSHlYSnNqQUlLVzRkbjFXVS9SNElEblB0WThvR1UrTTIyZVAzeStmNmhISlpPcDZkZWlkWWllV3E4NDlKWFF4R0FzSkFoUjhyZlp4cjkzemxFblR5UytZaFIrR3FqU3dDbGpPWElVdVF3SXNWNko2NFAySEpzMkJ1TjhzbXVXNFQ1S1l1RVF3Q296elRlNEJ2dnZNNUt6bGlDUktDK2Q3OWNjODdqMVduamNpU2Uvd1J3c3Nwc1N4UkFPNkhTUWdEYjR0azdNR0Fra0pjVEZOUVROcXYzTGlDdlFmRTNuZnlLRSt3SC9lcmxUaXJrcGlJYlBBa05vYTFwang5VXRtanQyalYvZXRjUTlEMFc0cURwMHhDOXRRejYvc0Z3UjFGNGxIaWdWdVZXT204WC91bDlFK2VKUXFUa3FWSTlFbVlqeFk1ajV6cjhtU3ZqQVF3YTYvdkhNZS9zVStOMTVmUHgvNnkvQjNGR09QRCtWdDdvSEw2cEx5SmNZaEhjUGwrVTBpdWlYbVNrRi9FSXROZ3dTamphUXlhNVVtTHA4NFlVWTQyR1FzOEpxYkJsdXVPNUJqanhxOCtibHliTnBkNFBvemZMTzFVM3ZMOXFUK1o0TnpZSVdkR2ZOVmh2QStoSTUvSVFxUkxNdTVHcjVHeUdNeXdFMzlrckk1bEtvOE04MXpqSEVuaVZXRndNOFJXYll3MlBXaU5meWVDUUt6UjNuTXE2MkVSQ0tBWlBKWTNYdEJkWTVpcmFRSFdvU08zb2ltS0RGaFRFWlN1SUoyNDkzekgvWnpCSzRyWUFOQzV3OHAxY0s1cXJtbmZJUmhSTEFaVWxuTE9mWWtpODVWajBBbXNFcFRJU3NERXVUTWR4MlMrWG43UE5NQXBrREhvVWQ1UndGS1VtRCtMaW5BMk9NM3pjb1dQTG5WSzM3T1V6ZEtJZ0ZRZkcvcXdMcmhQSlZZUjc0YUVGRVJSODdDNTMyZldCMlZDNlBDZ0VBN2lTU2dmZVFpT1dHWlIzUEw0amtBaW1Da1NaSXFyMTNTQ2F6d0pxeElQam5zUk1mZFRTTXJOTkFURkYrR25QR1NJa0pJdnF3TmlUU2tuZnl5cGtFZ3VaUVJ5VmRLM2VIcGlRWnNXTSszQzBrSWlsQmZYN2FyNzE3bUdqSXhXSU1XRTlDQ0FzRC9LZlI5NEJ1QWJYTWQ2YTZQNGkvMlNmcUt2NjNNOGYvb3dCU2V1QTFsZHR0S3pyQStPK3IycEIzMTVWRVNlbmFtSXZMc2NRMWp6ZWZtb25QUTkzK24vU0wwNkdpL3V6Mjg1NUY3M3JDSXFycm1Yc2tlb3htU2pzVlh4WGlIQVpJQitUT0ZGa1p2cWhBMFpSVmJtK1k3SVJjWk9yaVBxbnE4TTQxNjhGdVZ1eFJLc0JTWWpJYjVIenVJQklIUFNIZ1pWZG84azA3UkYrVG1PdUNNcWViWSs2UGtaWjk0bG8wdC81UkZWcm5ieCtKRkh4cXE2dXA4SFU3MU04WlBqWW1SYzUyMDgwM1RpQ0FUQnpZWE1NaUpVeitWMG1BUUNqcFNPVHNuTml2VlNzanFpenBuQlpxNXRPVkZzNXQ1MDNyalFERnlLRTZ0V0JxWEpuWmdrb0lqYmtQV081Ujgwdm9WUVJsd0lEeTVIL1lJVjRwa0dMVkprUUZIRXJpRUZoQ2lGa2FqN0JGQ3FHMlZHSVBxai9PS3hJSFNqd09HeEt2R2lHT3phREQrSlVpQ0VLQTVLa0REbEFwWk1SYkF3MU1WOUNCc3JtUHZSZmJBMHRaUVlCR1d3NXJVamY2d25STVZuNzRpVnoxSWovRWFMMy90QjVGWWxLMS9rSDYwZmdwKzFDOXM4aXhCVEw3Z1FiQVNrN3dnejdsbnYyMmZURndTaHR1Z1Rrb2g2OTYxS3lKSSs1OTRFZzhuSE13QXZPTVZic09yK2cxempvVkttZW50ZlBHS21WSTQ2aFhEeDhKbEMwMTdrYzNtbHlsNzFvRUI0RXloRjl5Z3Y3OGo3V0NZaCtrTGVINlhwWFNWbXlIVWt6NzQyRkdaSXFlc1VJcUtGV0RobkdEaEdVY29UcFpnajVVZ1JPb2Frd1ZkZVUxZTVsdklwelBRaDEzaEt2R3ZUWnN0Skc4Vk1HTXZ4RENhUHFUUHlSdnNpZitKOVlQeU01RWo5MWRIei9CbmZ5RzgrNXo2ZjNjdno1cHhSWmZ5VE4vR2NtUG9nRjNLdmNaaHQ1bm5PWEkvY1ZMKzBGZUZ3SHJJZ0prY2ZVRGZqRGs2bUwxSzJOcWRlWkQ1OGx3a1JSZTk1MmYramRxSk03L2pVa2RWSzBPUmxjVnQ1d1lUV0dQVzlkTnVKL25pWUJDSUJod1FhQlFsblNzSjhJaXVOWmFNVHN4U1hCekJybElXVFpNMDI5bXdBVU5pQzdzNTJRaVRVV3pzSVJnSlhuV0pSeFUydGpmSVFVRklDQ0pGVDdTVmdKZmRTOE56cjhnc1cyeXR4a3hMdWtzRlBVQ0l0M0tOd0ZwZ1lMNFd5NHFwZExrOU1nTzlaZFk0SVFBUlNqcTRUUEpTQ2xTR0lVb0xXRXBPZ1hHNWdncE55SDFOSUZFRVpBYWJNL0JGV3lKRDNIMHNUZG9sclNiNHN3OHhHWUVqVEdHZGdqQktNTm9nYWt6bHNaVmd1TjNxTWVMUVFLOEk5QXQ0ZUVTY2g4ZUR4TWhrZitwWHhraGljL2RwbkRoK1JnNW1FOUZOSTZldmVWN3dRdkdrc1daYnlzc0xKZTNNMEpud2ZoZVdhY25pYTlKa291aWpUZkQrV1lhem8xNjdGQTRBMFNyeHU4U1Q1M3JtKzVrL2VCRE02bXI2Z2lKT01UMTRYZFZRWCtmWEhFUy9UWDhwRnpQTnNVNjNJVXA0eDFuVThqenlRVDV2ekhRWHZHdEtPSUtVY2hGMmVlRnFUUDBkZUNyZ2h5N21tVHNFMjk0VVErRTdaSTNuajRiUnZCb0tybjhBanhFaVpxVE1ETEZOYTNwSHJ5bVdRSFZZNkVSNEk4Nnc2SnpDQmd6VWlFT1pMQWM5eU9oZlRZUklJcms1V0dJdlJ3QnYzU3pBWUtCcVdnUUd3dkw2WU1pRmNDQ3hXcjhBdUxzZjhLdWU2NzhheldjUVVrT0Fnc1FITFNSMGUzb21PUEJRUHhUa0tGZm0xaFNJMzZKUmpvT283NDNwditheXZweHpsSjZRSUQ0UkNtNUlRQ3VWd3pYSnpFMVpSa29nc2dwdEVXVko2bVVlTkZaZzRDc0xFdTFPWDVhV2ZLU1BIa0FoQ2s4dlR1MEZ5UXVJSUxJTERlNkdjQ1VIMVR5Q2RjcHlydTNZNnFodENRV0JIT2J2T0t5VGxtYTc1WTAyWkVsSmZuOVdCaFVUNFJiaXk0cjF6MXA3K2dyQ055L0NVeTN2b2ZzK2tGQ2hDQ3BTWGdXY3JNUUEreXhlU1pxNC81R1hjZDBTWjUxcEtzQzI1RjBYaUdJSVFiMEEyR3ZKTGtrbGpRS0N4QU9OVmY2dStDNG1JNHN2Ui9mcURLU2QxY3kvU2JJejVqdkxUYi9VZGZjTVlNRFZGTVdlNktGTlhXVkVrK0ZQaVNYUlAyc2t6UnhjWWx3Z1RZcEtsbzhnbUw1YXhGU0xBcXhkU003WXoxbnF3MGg5emozemFZQXd6bGpMOW12dkptM2cwZUE4akYvSzlJNnlVRFNOL3hyaTRNZDZqNWVmSUc3elZIWEdXeUZMUDRSV0RsZllhNDZhaFBHUFVlYVl3WUdLYUJjRmNudjZaQ2p6Z3Z4TkJJSFJHZ2oxQk5NQks0QXlYa1E0Y2dYcEFuTGJ5dHNNa0VBWXZ0eXJHci9OTG1EQVh1b0ZrTUpyZXdLNTFZb0ZSU1pRdEJhZGo4MWhjME9Nb2tBZWZFWUYxa3FrTTk0bWhNQ1hBaXZHWkVrc3l1SE5Od0thQnd5SW5WRE90eFQzTUVxT1lsR0VlMDl4aExPV1U1WWg0R09ocGU2SzVrUVNyRzdpN3VTMEpQOHBZbXd4OHF6NjBsZVd2UHZCSzRzbHhqWFdrREpIdnNQUEg0aFMvc2J4aFZ1NWRQdXI3dkRnRVVZTFRrb2RpRjhGdlBQZytybE50NWcxSTNFZElFd0dzenFaN1lCZkxkUXdrVmJidmpET0tubmVBa0ljZFJXSGVtYkxRWjdSSFgvQThnZ3VSRXZCRjZCSDR5OG45ck1OblBldFprd0pKTEluWUNzVEh1MFZBOUxjazVOWkdYNGlsT0FWNXpzV0V2TWFTMWJmMittTzk2cXRjN3Q0TlE0dW53dlh4bnBEclhFUFNRdFJjaStMTzkxRzRQb2V3T0NlREpmSUJVY2kwRlU4VjhvQkVrQ0dtU1dMQkM3UjFiN1lzejJxY1dPNEpHczZ6NDdGalJCcW54bkxxaDZqRzg2Q09sSFE4ZE1HTGpFaFppS3Z4bnZ0RGZIMVBYaWpMcWh6a1ZubjZPTmt5a2dsVEJURDJIUEtReHhPNWNJOXlFQWFyVkpDR1BOZTU4aWo1WEZNWGhobDV3a3M1NnJGTVI1QTlucDAyYWp0WkxSblB5akw5dzRoQ29wWUQxS2VNQi94M0lnaUVJQzRXVDlKSUlMQmRBSHJoNTFvNlRBTEJxdFVCZFdDZGtWWFA5V2x3d1J2R0VTRG5mV29mQnNwS3pFQUd3M0o4aE01Tm9MQVU1cVM0eFFtUE1WSHdoSlByemcxU2M2WExpVFZpTUl0N1lKRVFrQVNYd2ErT0dQMnlsMElaMkQ2eW9PMlV0YjVFNEdxMzRFZHVmM1BOQkU1Yy9xWXl4a1JZc0dRSWtpVEtsR0JVQm90Y0dSR3V5VFBucUIyVS9xckVIYnk4blRGbExxNkJ3UEwrS1BSVkNTRW5BSGtqVmlXNExiY3orYngzZ2pDQllONmRCTU1vQldOem5aUzVlYmhuUTZBb1BWSHlrdnBrUmNFNlpXOTdYdTdxakxQeG1ERTVXcklzV24rOGJrZ1pUMWtJdm5zcEk0clkrOHVVbk90UnFNa3pQaWZuRkcvT0hTbHZCcHc0Q3A4RjZ1b0Q1QWxGem1vMnBuSlB2SVdlVFRtWmZsRVgwMXZjOUJMQ0l6L2xid29tQk1WMzhvZXdJeVE4WDZaSnlSa2syVE5ER3BTaGY4Tm05TFM1N2xyR2N1cEdRZHV1Mm1mZVRVY3lrQ3lBWitKeDRNVHE5MTBNcE5IYlNjR25URjdJbkR2RzJ6QmVjKzQ5a2VmTDNsMWVtckgrY0VLb3JWeUtaNU1uRWJGbXBKRE5CL1g4d25jNW5RZ0N3Y0l5VUdJOWpnU0NoZVdGVWxibldqcE1BcEZsbEcvdEZnc0NvVk5qK3RqczJOa05Hb3JGb0hXZGdCQ3dRMEd1U2hUTjNGK0dzelF6UW1TNUxIRUNMRjZLeEROWEVZRzRSdFZMMVArWVdENzZ6YkpiM2NDWFg1eUJ4RHZBSXRCMkNwaUFrZ2dsaXR6OThpK1RISGxZSGN1ck9sdy8wNFRZSVVUamx0aktqS0ptMWErYjNFUDRhUXZCaWFEekxDUlJBaXlzdmQ0SGNtRDZSUCtJVzUxUVRkOUJZZzZTVWljZURNckFuNzdGUXlGUk5vY1JYWDZRdWgzblBRZ3pnZ3dMNzR3OGpES1BGd2xtRkdtdXl4ZlBra0E5bi8xUitCUzRoRXhRVUs3blBrcktaMHBwdE54ZDIwc0Jlay9Ha0dPbURmUXJaQjhCZDIvdTUzMFlVN3lPNlgrOGJCUytNY3h6T0Naa1g3OUVJbUNDSkdtM3N2VUxDazhkY3MzMXRNLzRaK1duTHVOeFhBSEJXRm5WVG1XVEJ3d1JIajlrQ0Q1U3BsOTRDeVRUTUNFeThZYU16N1BNbTdHVDZSRGZlYWFZSUgwY29TQ0hmSzlNSzNmU0p2SlBmdVZudlBrc1VOM1J1Q1NuQlZ3Zk5EaDlha1QvZHlJSUJLdE9SeVNnQkZKUm5GekFYSHFBeHNqT3hYU1lCQUorbVhiUUNTTkVrRE9zbndKbTdiSXd1SkFOVnZOMUJodUJNRWI4aisvQ3BqZXJsQkFGeFExSDZMQXlyZERnS3QvclhacFdNTEFFRFJsOHE1SXkxVGZDY1RrUEJhOXRoSk5vZGZFMHJBVmVpaVNFSW9yWjFJejhjR1pGc2RRTmN0WWNqMFBxSG91WUloMEQvYlFKTnZKbHZqZlBXZmNvemtKZHVQSzVoQkU0QXVVZzdueHRKSlRncWYwRUVZdEcrZGxRakxlRUlHYUo3WlVTcTBCUTJXQkxwRGxodVY5Y3gxN2x1VTdocVFlODlRVkt4Rnl6YTNGclo1cnFkT1djdE85WTRwU2Zkd0liL1J3bXlBTmlpemk0cG05bkdvS0ZqdUNaVmtUaTlkM2NKMzhzZWU5YVdmNG9aLzNlSER2bEpDV2Y3L1VabnhFWTVidkdlNWQ0SDRyVE5XT0c1OWc3OU5tZk1ZT1VPRTlzazdwNTV1aTk1REZqU1NNVTJvek1KOW54RlFiSzRKVmh6Q0ErcHR4YzQxRlJubk4vbEcwSVJLWUFLTmVjSjkrcTQraTE4WDI4Q1hETVZJczRqUkFnbUdoWGtySEo0S0RReC9LTnZRU1ZhZ3R2b2U5VFQyTWQ0Y3YweC9mMWFVUTRaYm0xdktaVlVxWXlRaDYwWGR5RTZWRmpSNTV4OVZ2cU52ZDRJZ2lFeG5MVGh0a0dPRWZncitzcW5RdmVwdWM3YkFLaHZid0p5QU1oSVNLYTBxUVVERlpCZU12S0cvTW1nRmhIU1FhNVB3cGR4K2ZPSEpQcmxJN095V1ZvcnR5N1JFNG90Q1NDd3dvUFI4cWVLellCbTZ2ZXVYMGtsb1ZSeW5LMEZBdnBGRTlBRVhPWm0yZGNsY3o1MjhPQjhvSURvVU9namt2UHREMzc3RnNOUkJFbkNNcHozT042M0tMTHduRFZjL2U2UnVuRG1PQmhtY1RpZ2UrNkNRNEVxNlMrR1UvaUlyUWhnc2YxL1pRMXJ5Q0ZBeWZlRy9FZVo1Szg0MWhzK21GaU9zd3ZxNC80aVhNeElRREdYc2dzMGhCbFRLRlJvaFJRdkFqQmtQTEtFdG04NS9FWXN1RWFCYWdNM2x5V3RYTktNQVRPcy9YbHJKcEE1cjBYejJlUnk2c2NSZ1VGNno0ZUJBcVdGOEp5YWYwT3FXQnArMTZzMDdLQ281U1JZL1VJZWNrT3BzaXBOaHFINUFncjNqUEpCenFDbHlGV3ZYUGZJVXVPNHgvc1FpSzBrNEdrVEhsY0QwbGh0TG9tRDltU01sMEwvdVNKY3pob2syUzhpdTloUE1pYmFkUThNOU02NnNiNGtzZWY2UnR5U1RtTUQ4YVh1cGdxTkIwcVQ3eS95S1A2TVZ5c0ZpTTdqUmtHV1VnWFExc2YyRzhjN3pXbVRnU0I0THJGcUx3VTFoNUxtV3Rjb0pydjR2cmFDNFNUZXYwb0NJUjV4T1dsZnJ3L1dDM2h2ZXhOSU5SNEdYUmsxb2tqSWVFdnJ0WDhpbURlZzhBL0E0RUFTUEllWGNQT0RXYWt3MkNsaENNTVBVY1NIRWFaajlNWW1RL0UrSmZYd3VjWkJpYUJzMjVpL2FtYlJIQTd2NkRISkRoYUtSREJTVGpvbzdIbXgzZ0k5MnFQd1gyUXhOcnp2c2VVbUJGVEhPc2sxdDA0MVVKZ215SWhBTFhKSHlFTmQ4b2lidkIxbm5HUXZMRHpiRW9OY1lnUVQ1MG9wck94VjhOQjZuN1U5NlMvd1NLS3p2bG9iUWVuSENrZzNqaktMOWR5SE12SU5lOWJIekJ1OVdYblk1K1FMd293eXN3N2NaMnlKeDhvTU1vUlNSMFRzc0ZUUWJtdkNxNGQ4enFuTUhtWHlRaEtXSm1SQS9Fa01sekltM2hWMG81NE4vSVpNVUtNODNuVkVZbGgrY01UMFUrN0VYWGpJN0xNdmZxbDhVSld3ZFlmWW0vWk5FS2dmZVNrc3BiZmo3RW5Sb3VNU3oxQ1JIZ1ZKQ1JwSkNyeWVRWU15RU9meWRveGVVN0lvKys5cDNnOVBZc0g5eURwUkJBSVVmQjdCWE54ZHdGc09mamtJR0J0MnoxSFFTQUVyMkhMWWlLU01PUllIYVBGbXdoL0NpWkx4QWdVRWRQbUNzUDhFekdzUEo0RDd5dlI5M21HSXlHVFlDZUQxTEsrdUczZFkxTWFpVkF4LytnYU1zSGRTdGc4dkx2YnVVSU43dVdZR0wrVklmKzZBNG1ibmpEQjZMT2RiWDVMZ0hBeCtIbkdlQVV3ZlVyUWxNK3FYVFhoUkRBa2xtZHFUUC9IL1dyVEpaczlXWDFBWUkySkYwYmRsOXNrRDFKRlFLeVRlREtXclQ3MzU3ZEU0Q2lKa3lBSVBUdExQS2N2bHY0SmNqTjk0WDJ4VUdGOWtQU2ExN3htZWhZY3RZa1hDKzRFcmpwUUZQSHdIS1Q4YmI5SE1COGNsditpN0Z6WHY1QjM1Nll2ekowN1I3QXpCcEl2U3RVOStxdnI0eDlGUFpJNHlzLzNzWjZqK0NnMzcwbWNrdWsvMXlrMHowektPM1EvTXJSZlloeUV1QnNiM1BuZXZ5TUZTeWNveTdoajhFVFd1SWFBcG0wK0l5UHlqRGpCU0xzWlIvTDRqdEdDYkpqU1pLQ2s3ZVFKbVNpUHNjN2pJSyt4Ymt3em9wUm4rYk1ZRGVYcHc1RlJQbzkvdkRiaVVIaE1ZSmZ2ako4RWtJNmtLQjRWd2RnOFBmTDdQbU11QmhtUEtYbGdmUE5JeUdmM1RwZ2QxRE80dFFUQ2l4RkJqa0ZqbVY2ZzgvR1BtMHhuMFJGR2EzYS96bmxTdmo4S0FnRWJsb1RPeDMxSVdWSndPcm9CcEFOYnJwZ05nQktrWTJDWi95ZEV1Qk1OY29yUW5EcEJrUGREZ2V1VUVyY2FwVUdnVUpLU1FXc3djbjJxQTZWcUVDUkMzL0svSkVyUTNEdVB3N2k4TVM1QkRKeFZJS0JQV1Z6MDZ5YmVMWUpUNGtraHNDVEVndVdQNmJQbUtWdkNoK0JqQ1JBdXF4SVB4a2d1V0ZHRW5Ta2lXTVZsSDVldE1tQnVQblpWOGx4MVdDY1J5QlQ5bUhqNFlPUnYzRU5DSHROWWUrMEVhWjZiOExiZkFPR1hPZTl4U2V2NG5OT2R1NS9pMGMrV1V6WTZJNlRQNVVSQmVFZUlOc1VRMTdoclNINzZmdDRsa2t0SjZzZlpnSXIxeWh0QXljQmFYbU0yeWt5WkxHN2szSGRScE00UlhKNE55c3huVnJNeFlYenJRNlllTE4vMG5UOXhLNllETTJmUG03Qk9Zc2pvMytxcUR5WU9RSjlUdGlCUWJmRWRwWjduNnVPVXRNOHdVZDk0RWRTZkFrYkk1Q0czNUNOUFlaQjRndUNCZktSY1JKcXNHL2ZYSUNmaElnOHlJZENWaklPYnNhMVBrdzBwdzVIU2orTDMyVHRKTElUUHBrRHBOWDgrcXdNaVFVWmtXb2ZoUlBiNTNoOENRVDltR2tWNUlWSWptVnNILzYwbEVCckpQV3l1blBCazJUb2Yvd0JFNE1aVnN3NHdKeUh2VVJBSWdrQUhoVGUzWE54aW91UE41eE1XNXRxdytsanpYUFVHZEVqQ01yYThBMW1HWndDeVVDZ3BMTjNBU2RDaXVUekNncGZEZ0JoM1VsUm12QnFKeUY5K3p2aVpjS0g0Q1JqbEkwSUhTUlE1VjZYRWM2QXRJUWZhd0dVcnNlNElJMG03UXF5bUM1LzZCeC9DbWFDVnNvSE84dUFtRkNpSXhIa29PM08rbnlwcTUwQlJwMzQ3Ri9jNWdTdDhMV05MSWtRSnVWVy9sNEh3akRFdXVTY1IrbGx5bWVzc05GaXM2eFdrZUNJd2tjb2tmVWQ5OWNseGY0aDhmNjRkOVF2N2kraDdzZEwxRDMxZDMwTUs0aVdBMituK2pGdlR3ckdXbFVrSktvdmxUWWxTUWxHQVBpTWtwZ3BETE1abHdpSDZ4Z2E1YmRvaDF2VFkzK2E4TStNTU9lQ04wajdLTExFLzJvUXdrZjlTUENnTUNjK3pxb2k3bitjYUh0cmpIblZtK1d1RE5DcnRaWnpFR21oNytxUzJCeWZUbGtuYXlYRHk3T0NrckpBbWRmRVpBZEFPbU9kWnlpUmp5WURjeTZoZ2ZLbXJOc3VMdEpBZDNrM3V6VkVaNUdZK095TDJNUVR6UTNXcDd6ckhyU1lRYVNnTFRNZXN0QnVCTXlFUWIzM3JXeWZYdjA1dWdMQWNXQ2dHcXc3SUE1U1U5ZEtVS1lzWE8yYjlFRENVUG1HaExuc1JDTzdBRUFoQ0laYlFHS3VRT0FKS3dpQmRua05WRjFZekM1NjFmcllTMXl6ckJhbFNkOVlGRWl2QktSYVY4L3dVdWNCS3VDNG5tQkdJaWQzZ1hkbHJqd3pUTlFud2xCOW1zRjVPbmlzUWJWVVNWeUtBamhEMVhua1N1SklsZTFTNDF6dlVKbDRmeWlma2FDelB0TUdxS1VTRWJ2UUlqZmNJK2hPbnRFN0tGRThzUjhxSEVvZ0FaN0VWZ2RpTktPOVh5SjMrNFozcVk0NVIzTTdIUDMwcFFhbXVpMmZRM3lpaGtGbmozSGNVcUw3aFhaQVJybEZzaUwvelZUK1FwcC81VG41bFVwRHJrZ2V0UkxTamJLM1FTa0xrbGU4dlUydmlEckxrRTNuS2ZZd1Zsam1qaEtMbERYQWZqNFVwc3BUakNDOTVjaTNlR1orMTJXY0VZQ1RNMmFkRVBCSTVLQyt2T0owbGhmeG0xUVdTd0p1aVh2R01Sc0dIY01EY21QUThHSnJ1TlE1Y1Q5MFFvQVJUdXFiOGtJaVFEcC9WMjlUd1FkT0pJQkFIYmZ4SnYrK2dCSUxIUnFkanVUcWE4MHZuOVpteVhFNEV0NVVMQmdlQlpaZEhqRnZrdlhzb29sWEtNRkhBSTduZ3ZYQVBwV2JlM1gySVFlWVNEYTV4V1plNlVPVHVNZS9IalhrMkV5SGwyUUlaQ1RMbkJBRnZqTStVS3dzaGljS0hrWHkrMXhaa2dSQWVpWm55V04yckVxRW5HRE1wOFJlZVF6R2JJb0tYZWVwVlNSMElENjVQd3N6Y0xPelVLZE05cHBCTUExRkNTQUlMYWRVdlJWcHZIM0kwUHN1elRTMnNTdkp6aTYrVG9yVFVrVlhINjZWZitaeTZqNXNLclZQMlNjMnJmMzFmWCthWEpiVVVPcnp5RjBXYXo3SEVLVW9LQ2RuUVQzZ3lFUGNFK1JxVE1TNXlMd0xNUTVYUGxNdXFaQ1dYUE1pMXZrOEcrTXdydUU3U04vVkpucy9sRkFMREVKTElGRjYweUJzS040U0g1VzRhM05oUkQyT1gwdWJ1cDZSWi9LN0w1MmpxM0ZoMTdvL1hVVndYbkh3MmJjcDdtS1hWMmNhZXA4RXpZRDdHT1NFUlpMVjdQZHVxTHQ1MStjblR5RWJreGg4UHIybGp3YUR1UVRpUU9PZnFvRzNPQllRNzF3WWsyNVNUOStlM2VDeW5kVjIrdmNib0JOdysvNHBBN0FQUUpuN05mYXNUNy9lbk02M3pxMnM2cWtBZEhTdFRFenBZdkE2RUNJR0N3Uy92WmlaV0FjdmxJVmhPaElUcnlocFhCR1FyVnN4OFRKNURZZW5rQmduTHlScHJTbytpRFpPT216QXNIbkV3NkViUHhWanVVWjZ6QWl4WDVQSlVYOVkzTEFtdTFIMThQcXk1OGdrTFN4TUZ0TVc2U3o3bDdPVk5JZWl6L1hUeXc4UDhyZktVNi9jT0lueVNKMGNra0NCYlRvUWY2NFd5WGs2Wk9vckZJZzlCNjcydUNucmxQdDZMSkZEOE5vQmJKOEdVRjRRQTlVeGVETXJSa2JKREtDcnRSb0J5UUNRcHRNUWx3TTQwaDNnVWlpdUtNUXBGa0crTUIzM0UyRVZJcy8yNmNjYmp5MHBYbGo4eUlrbzdpblRWWm1IWmtDNDdrNmEyaUNreWtKVlV1WDY2SXlXc3p1UUh6eGo1a1A0dUxrcTk5Qm5YZU5yMEU5Y29VRWZ0NG0xeFhDWlN2RnhrSGFJdWIvNGUzZ09JR1VvK3d3aFd6aGxkNURIWkNBdGprQ2QyREJpbXhPMlBJejh5Rm04ZUF1K2FzaEUzTVJicXJRME1veVR2RVZtUzE1OXg2QmdpNUJ5WnlmY012N3hUMXp4ZmpBUzVrSGNVYjYvNndHL2RWQVJpWGNRMklEOVdUU252OTRjbFU4SnpFOGFkemtmWUdDQmh0aUVBM0hnNklBVTFKa0ZZQnVFWUFEaCtMMW9mNmJCcVFsazZQYUt3S2o3RnN3M3lWVWxnYkpaQll1dGlBUWhCQXl2VzFicHo2NnVlc3duWGVIRzhqK1ZscmdTRDZ3ZGR1NjF0ckVmOWFGWHlqbmdrVmlWV0l1SHFEKzRJVzZhZmx2TW5XRzU1WlVRQ1FVMmh6RTJFclQ3RDIrTWNPVU1rdlgvOWptVzJWM3ZtUHVNazVrUHllTHQ0OE9CbnpHU01PNDRLeG1kak0ybTB2RE5kSnBoWi8yQmdSQW14YkxudUtTL3lRcG14ZUZOV2pxYnZCRml2U2hRb3BidE9RbjdVeGZPMGpVSkRyTFhGdGVYMlVaUnAvOWdHOGdOQjFvL2NsenluTzJZNmc1eTFlWnU4Q0pDeHRTb1pNNllJalNGNVBZdlJoYWp3RkpDdDZxdGZJd3ZMY1ZrSmlFeXc1K25xbG1CU1k1UlJzSnpYTTJBbkZndkI4dXgxak0yMHJ3aEVrRGlCUjUwSGk1MlRZc1VieEhIUEVSUmM0OXpDWWRvNklpOUNsa3ltYk5kMXlMMENHTEgvUk1ncms1S1B0WkF5Y2hUTElBaHJPWVdwczFZRU9ubW1jc1ZEOEV3UVlnbEFYTDUzV3o4THZ0Sk9FZFVJRWdISSsyQis5a3dTUWI5c0JhWThaRzh2QWljUHE0Z2k0WFdJRlpWN2w0K1pEdVB4SUtBSVduMXAyZHV5Zk4veVo4K2hJTWJuSVZBRXN1V3JyTjhFN1M3ZmU2NStOcWJ0V0ppWUEvM0lIOFVYNVpkck9WS2VFbXMwMXh4NUlIaDRyRmhnQ1BBZUtjTzRrN3dYZlNMVGVXUUliOXh5WXIzenlLMUt2RzNJeU55VXZXSFNGakVPQ1hyTTh1SVlQZ0ttYzU1MlVhSVVkMWJ3c1BxRGxUYUc2Q1ovcGpqeTJSRUppYnkwRk5LWUNvYkw3V0IwR2IrSVNyeEJQSlR4akpDZnR0c25Gek51eG1sS1cvbm4yVHl6bEhjK200cEVVTlFuMTVBUUpNVm5CTUdZRnhjUkhMUS9IZzVISHFEUlk3SmMvMVdmdDRGQVhMUURVT21JRWVpUjk2M1B1YmZ1Qm0rOU03VStzRnEzS0ZxM1dscVBabTY5WTdlKzlHbXFSUi9rZGsxcWZjQzBUZ3BhZDllMUhnZzU1ZXR6YzZmVXRGdEJyVWZrdDk1NXArK1UyVHRyNjJ6N2xMd3VkRUhRdWdVOGZkOVhFYlJPT0ZwM2g3WSs2Rm9uTTYzSFFMVGVjVnRYSHEyNysxcFhJTk94SzVEV0I5SEtNcmYxWXZlNHRQNHJrNjE3YTZaMmRvSFR1a2VpZFNGMVJrM3FDcmQxSVhWS0dWMEF0bTVGdGU2R1BlVzdYT2pDYUhyZlhUaTFMcnh6ZWVXeEIrTzFIbHpiUEs4ci9OYmR2SzI3Y1ZzWGxpdno3M1ZSWCtrckFOb0ZGMXl3azZVTHdOWTlFSzJUMGViZGQ0L1p6bmZuK2trbkQ2MGJBSzI3OTF1Zjh0a0ZSNS91YVYxSnRiNmNiM3FQNDVmZWY1L1BiOTJyMDd4bkNmYWRpRXo0Nm9lZERFNzNka0xYK3RMYTFqMWxyUlBhMW8ySDFpM3ExcWZ5V2pkZUp0a3hsdTNjdU8zN3ZyUk9VQnFabzM0OTdtZksxdWY5VzQ4YldyNWx6OC9xMmIwclV6Mjc0bXpkc0poa1RDYzVVeC9XaGo1VjAzcHNSdXNyRGlhWk0yTFJTVWJycEdmQ1FoOGl6enBSYWoxbXFYWHZTdXNrb3VuakVwbWozNDZwVDZkTnNsSmY3akVVclh0V1dvOE5hVjF4ajlsMnp2c3kwdGFYaHJaT2xGcVA0V2s5UnFqMXVJeEpOaXEvazYvV3lVanJ4dEUwWHVEWlk4dWFkK205a0FVOTdxUDFxYzFwN1BZcG5LbHNZNUJjZEMvWjdUbmFhWHlRNXhJTWZOL2pNVm9uU3RPMVR2Nm1jZU81MnF2ZFpNMkpTNnVZVDEzYkg0RjFQQkJXVUhDbG1mSklOQy9HelF2aE85Wjk3MWk3Z24wdy96QmVjMnR4dVkrQmJKaXQrN0Q3ZFJLTGhqVmlQcDZiVDZBZUJsN3BjQkRnRGZKZXpNa21zZWhkV3hVa216ekhlVXhVdXAvdFRtTHhxYk5nM1VvWElwRFZBN1ljRjZ2QStvVFJPbjljNmFZdzQvSmY5aGJ5Z3JIZVdhMnNYTk1qdkVBOEhvbU5HT1ZBM28zWUN4WTYyYVI4VnJKNkNjQjBURnhUOHAvdUtJNUdIQUJ2aVpVaXlqT05ZbHJOTTNna3N2Y0RqNlVrc0ZFY0RXOFd6NEhZSTFhMCtsc05abnBBN0pHNnNOREZqbWpuaUIydmJtUmtzRFdORmxsSWppNXY2cFo0QmR0MWU3YTg1Q2VjSFFVKyt3NHVwcHg0QzJETU8yR3FXdXlJWmFtV1g2cUxLVHhIejAxZEJJS2FWdElXM2d6bnZqY2RtVGJsbnRTVlI4SzVnRzhCbThIcGRMaVAzMjJEQitMQ1BZTEhXdGY1TEFUV0lSRG1Ta1h6Y2pIcWVHSU5NamgwT2gzZFVlZDNGQVdjbEtrRmJrNXVQTjlUK0FrcTBubEgxM1B1VytmNHJHYzlheHBNVmlZWWFIdk4wYTlUNXJtZU45TWpncllFZlJHK1ZqTnNjc3B1bUtiUTFObUtIQXFyMHFjUlFPYTV5QzBuTmhielp3eVBZOXAxWXozZmMvTlRVQUlISldQV2Q2dkl2K2tEaWtjTWlqeVVySEZPK2VsSHJvMHJpbEs3dDd6bExUdlBZeHk0SjBHeDY4N0JJd3pMZThIa09lcUFRQ0FKVnZ6WTRweHNvMURUWHNkeEt0YlVnbXZHQXlMa1hwdVg2V2NVZk82TExLVDRYWXZTenIxaUlBUlRqbVFJd2JYMFVwNnN5bERYUEpQU1YyN3VnWDJtT1V6NUlHUDJxMEhTNEtRYzVBSWhRalpDQ0JBbk1wb1JJQThkWU5vd1V4blpuQW81eWoxa2Fmb0ZRcjVPS2dLeERscGJsbmNkQXFGcE5pZlI2Vmo4amxpdStlcDBQdlB3cnV1MDVnanQxSmE1Yk1HVHZCU0lpQmdIM3hIMkI5bHhjQmxtYThReGFvTllrSklZQ2ZWQVhJNHpFYUlzQTB2bGVGOTRXN1l0bWJQbWpXRGxiRXNRb2pxYmd5ZmMxNTJ6M2JiM2M1RDZVbjZVb0RIaWowWHV5S0oxakJIQWdxZEl4djBDS0VWTHN2T2JOL0x2UmY2dE5yQkVXUjRya0hnOGtBMmY5NHBGRXFqOThCNW54ZHNsOXVEWnozNzJGRy9EcTBTSnJxUEF4Q2dnQ2NzcCswQlFzTm9qTUhOc3QvUHhUenNTb01pVHdmaTVvSzkwMHpZQmo3d3NVZHJJQXNJekVpOEtuTmNCbnVJY2xBM3pNWDZCTWVWNmxtOGlWNTVCZGlRbVlSbG5NVWJ1c1lKRW40OW53VFh4RHBiU2VxYlAvdFFqaE01bnBBNWhvdVI5RmtqckdBS2szVDduK1l3elJ1QTZxUWpFT21odFdkNTFDWVRtVWY2MmVkV3hkRDV1TFZIL09ycHIvbHd6ZUxNRUtQc0duTTRpT0NoMFBBK2V1YXljVFdjWTJBTEZqaU1KM2lOSUJHdFpEaGMzWnl5STQ2aFRQYk1RMFA4b0ZTU0JGVXlwR0Q4aEVjNnppc0o1L3F5NG9CVGRaMXdqSUVnQjViS0twQ0hQbExQcEV0czJzMng1TUZqN2ZlNSt6eGRCQ1pJeHE1SnBqTDMyUFZtVkgrbFEvM0hmRjNWMUxmdlBwSDB4aW54bWpNUjdRRVpTcU5wTjNsSGlTSUJBOFN3NXRlZUkrMWpxS2NjMFNNb09tVWlRSmZsSk5pRU5TWWdWdVNraEEwZ2JidzNaRWV1ZlRNMVVrWUJVNVNOY1BBaVNmVE5jSTNmVWlaYzRkVkNXODVBRDV3Z2pZdU04Sk1MZUxObDZXOXQ1V1h5ZjlxalBPcWtJeERwb2JWbmVneENJTk5FcUNZTkFCNHVySzUxemRFMnlJSFJBRWZCWXNRMXJEak54dzdLT1Z5V1J5S3ZXbXEvS2U1alhyQUxSWnBiYW1BaHBXLzJ1MmhOaHpGZm5oY0JSSUpCNG8wd2pjS1ZUSUZFTzV2ajEyK1UvYm0vS2s3emdHUmlUSFJ5NXpaZVRNcENNZFpNNkxQOFlYTXJ3bkwyV2dTZlA4cEdpUlFpUUpjUUpRZUd4cEloRG5zYjJqanRzdWk1K2dGeVROMjNuR2ZDZDZSRXhRc2hHRkszcklSK1JoMGdGR2VXN1gvekZYNXlPNmtQNUoxbjY3bnVlV1VmZVhDbS9zNEZFS0UvOWtRdXkxdzZ5NUd0V3VzaVBwTGsvOVZFWG5nUFhVaS9ucG14TTc4RWhtM3VGT0tVZnVJNFVlWllWWG93aDlVQnc1cVlpRUhPUjJzSjhaMElnQkNZUkxJU1JUcytsbVE0Nk1tdXdjTy9wZlBLNzd6Q1Q1WnltQjFZbDdrWS9ER09nV1ZzK0JnU3V5bjlZMXp4ckZBNWp1WUxPdUJZckZRSm5Hd0cvUUVrNVNJbEZva3dTb09pY2dvaXk4dG1mUFJEc3ljSnlYazRzOGloZFhnb2JneG1UeG51czVlVjdUdmVaTjlPNFhVNkp4NGtTWC83K2RKOFJKNTRIeXBCblJMSzBPMjJMaTk1bjA3SGtvbk1Ca3J5bTJzNkRPS1lRQXRNSFpDRDNQL25tSHZmRys2RThlMXRJcG13cCtPeERZYW8zaWFjbVU4RUlodzNZZUN4NFBrejlJZ1JpTGNoUzdmRDdRWkpualJ2ak1kNU1PN21lNlF1a0F4RnlQV1FJRHQ2emFTVnQ0Q1ZCUkhnbGtKdVFRbkZ2M3FlNkt0UDBqUjBzNTZadElCQ25YeWZXVzEzcDhCSG84NVN0ZDhyV053R2Fsa2oyK2ZGcCtVK2ZlMjQ5RnFGMTYzOWFXdFFIL0xSVXlOSy92aHZsdEJ6b01HdlRCMG5yYzZXbkZPbTVQUnA2V3RMWXJZZHBLVjhma0sxYkFLZmtQZXdMZmNwbVdpcTFxdHcrQUtjbHFLdStxMnVGd0ZFaTBCWFB0TVRTTXl4NTdsYmw5TGorWTFnN2orM0tabHBDZWFGdWFxMTdGMXNQbkd4OWw4bldWeVRzNU10Sk54cW1KWU9XYTF2S1RRNTBaVE9OeWE2c2ttMzIwYk9lOXJTbnRlNnRhOGFSSmRoZFdiZE95RnVQYVpxV0hzNHU3Rk1adTZKczNjdlNlcnhXczdTeEsvZHBLWGduSzYyNzVLY2x3MTFwVDdMSjh0SHVsWm1XaTNadjZiVGtVdHZKbVRGMUkybGF0a2tHd3FBcjUyblpxZVdXNm01WlpTY1UwM2RkNFU1ajNwSmx5NGt0ZVpVc0owMlN0MC9IVGgvN05OTzAvTDE3QkZwZjlkRjZ2TWkwckxOdjFqVTkwM0psUzlkN0RNZTBuTHFUalJRekxjVzBYRlRxbTBCTlMyeTF2eE9MQ1VzNGR2SXhMY05WYjZsN2wxb25ndE9TMis2Vm1wYWtxbWNQSUoyV2pIYXkwZnFVVGV1R1dPdjdZSnc4K1RXWERWVyszUWljaVFlQ1c4eXY2SEZuK1lVN0RCbGI1b1h3RnlzRzY4Vm1XVGxIa2JKaGxFQy9KRlpSSHhmVDMranhzQW1MNjRMcmpqTFpURWUwK3Fwa1QzeHp4NVVLZ2JPTlFGZk1weXpCVGVSL3hzdXFJNitaNVlzMllUcUlWMkdkZHRwMm1yd3dMWm9wQUpiMHFoMXA1NVpMSGxpdVN0NlpzaUdiZUIzRURtaVBPWC9lQTIwbnd5eFpITDB5cmwvUXB5MzJTdmxoT2NHcHR1eTM5RlJ3ZUtZUnlBUDRlVzdpSWNqSTVhUXU3dkdkZXZBY21JYTFHNlE2c09iVjIzYzhTYndDeTdGZnlzeXZhSXFwQ0laa3RPV2x5czQxM3BYY0wramRNM2hCNUZGUFhndm5ydk5TcUo5bHJhdCsxMmE1TGZtOERSNklXc2FadDdYbThVd0loSTZScllnSkZ1NHZIUzNydGkxLzRxcDN6ZDllQ25YTktxL01ibXJDTTB3YjJCdENFSmdCRUhmbGVCTVhZL2NDakpjTy9keVVqc0c3SE91UUh5eGEzbnI2MEN0UUJSWUNLeEF3WjA5UjVyZEtrR3Z6NEJSYnhpbmxJdnBlckU2dW00Nndlb3J5RWh4OFZNbktEUFd3NHlTbDd5ODdMZ3JTUG1peXZGRzVZcE1rUVowK2E2dnk3Y2tneGlIdERSYU1IOWV5VGZmcG5wL2dUTUdMNUNybFRBWWhMTW9icHhOYy83NytHeTNMeVg0Nm5pY1d3V29NN1E5aHMvUldPY2pCYUJRdGwrRXpKUzlteFZTRDZhVUVVR2JwWnRxbkhxWkZ5RzlrSmZ1b21LNUJITlJEL0FNQ0kxbFI1OTUxeUZ3UmlBbTZrL252VEFpRU5kTUd5emd3Ykx1YXptbndHZlFFRkZack1CeGw0Z2t4TDJsWmxiWFRCc2FxMUYyczArQmU5ZDFoWHJOOERCYVdFNXF6VEREVXVzdWdEck5PbTFhV1FGenIxMFd6WjA1MzArcDQwdXFqUCtxWHZCRjk2bUxINHFWQVdmMytlUFBFR2tUNVVXcmVrNDJLOW9vM09neWNlRHJFV3l3blhrYno4Z2VKZjhoS2lWSCs4QklnK0ZsaUttYkpNOFJ2YUNzdmdPQnM4UWJyRUNZS0Z0bklzdERFTkFoNnBORGhMcDdBY1JVSnNIZU93Rk1FU2g0eEUyUkg5cGhRM3B4a1MvSFVBUW53bXhsa2NWYUI4R0I0UHE5RW41S1lucFBsbytRMkFwSEFTNEcyNnNJQWRCUTdzazRxQXJFT1dsdVc5MHdJUkg1NVQ2Y1NhQk8zR0FzbmdrZm5FMWhsMDVhenVaeFNnQmczNUtya3A2Y040ck9SREZvdVlrRllsbFNOMHl4bjQvbWIvQXhXRW91V0VNdHkzK1VmQjlyayttOXozZnl3SGZlOWZrbGgybmpOT0xhaXdyNHVQQlNpOUYxRHlCa0JQSHVVMGVtV1lKNHBKcXhkTzFHdVNtUU14Yjl1b3ZBRUNpNm43THRnK3NJU1N0TW1rVnRScHN2M3pQMXNsUWZzNE1yQVFuNEVScHAyOEplOWNaYkxnenY4SmFRQm1mQ08xQkhKZ2NHYzVCZDNrUWhUdGdJd3RjdW1VNExKVFhzZ2llckFXNnd2SlBsZXZYbHVFVVdrMGp2WFIxdy9pTndzQWhGMFQrRHhvQVFDbTllaHVNREdZMGdFc21BT01SMk9BRHJUUWJrTy9Dd1ZnMk41QjBMWDFYZU1XbDZuM01wN09BakVWVHB1Sm1UdTI3dGhkVlU2ZXdoWThjQWF6MWkyMURyV01tWEdoYzY5VFFteVRGZFp6b2RWV3dTQ1YycFZvdUFQTXZXSFFOaFliamxwVnpiSVFtRHRuVURaSHdaQm9qVDNXbTVxZWxWZlg1Vk1FOWx1MnNxeE1jSGMyR0NNelVtbXFyd3o1S0QvZnNoazNQRmsyRGhMT2VRK0w0VHpUUFBhMThKbk1oekJjRDd1bnlHR3c3WHNRanFuSHZJVWdaaUwxQmJtT3lpQjZEOTh0YlBVU2FDTk5jTG0vTEtlUFB1d0p3Z0lBejdiS1J1dG1QODBmV0RYTjBMUUxuZVZqZzhCSkk2TE9QUHdZMDB1NklGcTV0NUhkL1A0ZlowZlBnS0M2Q2cxeWdIUk4vWEc2dlRaTkVkK3Q4STRIL2QzT2Z5YUxLWnB4MVV1Y3NIYTZrUEJycHY4YWl4aWtHREI4WDVLMUxTRjhpbllnNVEvbHBkejNnWUdFeXZmUGcwOEFtUVFjc1NyTUc3em4zdHl6QjR5cG9mZDR4MVEzandINjZUOGZJQ2c3V3dNQlVOTGNjY3R6UDJVOS9nN0dBZ0hzaWF2dnhoYjRzWXNwVVh5UnVLL1g1MktRT3lIMEJaL2YxQUNrWUJKN2pIQk5nWmlMSmpNKzFFU1hHRHBpSHU1Sm84U1BzKzA0c0dHS0FiT25HQ29vNnhQbGIyWUFySll2SHNsaWlwVzBWNTU2dnJoSXNBYXA3aU5WZVRCYW9Menp6OS9aMnJKSGdmcmJDRjkwTnBsMmtRTVFEd2RsSzE2aVdVNGFMSnpKSTlrZm1PQ1loZmt6ZHVTNXh5MDdGWDN3Y3VxQm9wZlhBZExuZ0tPTE56cjl6bFNsbmdnQVpEa2xsZ3pzVjBIU1VnUkFrRSsrMTBSaGgyeVlJb0ZDUkFjaXhDa1hqd3lTTHp0cnZ1dmV1NU1ZV1RQRVBnaEk0akUzRlFFWWk1U1c1anZJQVFpVWRHQ2Jhd3lzUEdJRHBmcGkzUkdSOVprZ3BoNEkyb2I1eTNzSklkY1paNGhNVEdKTGgrTForRnlueCtXSlRpV1hlZjdJMkRxY1ZRb2pBUEd3cXAzdFg5cEI4dkJTdWZHMXc4WUkyVElZUkIveXhDUkkrMFRwMldhWVBrWE1ROVc0MVB2eW02VDR4U0FYR1NrdjcxMjJqeTFwRE8vNGxuYXZDclp2RXA4ZytCWUsxT3lHeWFjWUdRcUk0YWgxUnlTZCtNM1N1YW1iU0FRdFpGVTE5Wm5LOWxNeHUvSmR5RS9iU3JTOTdodnZaTzJIdXl6cXdvOWFudmFmTWFtS3QyZE4yMnMwZ1hCcmp6MTRkeERvSk9IMWoxWHJidDFUMm04dnRUalpsb1hhcWQ4VnhlT0hvRSt4ZGU2QzMzYWFLaXZWcG8ySHJJcFhGZDZSLy93VHoyaEs3dG1ZNnUrcW1yYVFLbGIwYTB2TXp6ajUrdHZuWnhNbTBqWmhLbTc2bHUzek0rNDNGVUY5R202MW9uUDFNZDd6RURyTVJpdHg0UzFIbXZST25GcFBiaDYxVzJIZnMzbVhqMHdkdG9Zckh0MVd2ZnM3WHBHSndtdGswUGJJRXliUi9XZ3o5YW5vbHNuRnRPMWJpUk8zN3ZKdGI0RXZuWFBST3ZMUW5lVnMrMGZpa0NjeFRkb1Y3YmYrSTNmbUhadDZ4c3lUYnRMZW55UEVKNXEwUU90V3A5VGJYWmRTN0xMbTg3YWc2QnlxWTduS0FMZG9tbDlUZnUwcXgxaGFyZS83dEp0UGNxL3ZlaEZMMnA5SmNaWlZWam42R3ZZczluSVF2ZE10ajdOZEd4RVRoMjZCMktTR1lkSlh2UzlIdWR4Nkx2aExvT3BQOXRsc3NmNXRCNmNPZUhacDRoYVh3RTJFZVMrMzhQeUxZZitHWEg0Z1IvNGdXbEh6UjVUTk8zQTJ6MDZyVS9yN2p5clQwVTBoTjV1bi8zSEI2ZXhoemgyRDhSRUlydUhlZHBKMHcwOUtMVDFLWkJwWjBydjVpU2xFMld1WUlSZVlnODhQTFlCdkZmbjZKdWxUTjZHUGsvZHNHeXBCeUJOeHg3d014MjdpM3Jha25VYytEMkFhV0t3MmxTcEVPalRYcE5YcXU5bzEvcXYvMDNiSmZjNTRzbmlQR25DcWQ3MnVZY0FUMDZQRjVpMndlNnhGN3NBZU10YjN0TDZVczVkMXc3N0EyK0Q3Yk1SQTE0VzhyZi9zTjlFQUd4bDNaZG9UanFteDJlMEh1VFplbHpFWkFnaUNVaVdyYlRKZU50Zkl4ODlWbVRhcGx3OSt5WjVyVTlMSEhhVmo3ZTh1Zk14bTVUUHIxTUs3TE5XT0d0eEJjNkk0TzFvVHFzY3pLVWRaVm8zQnNKNmFuWHpaM2N5UHgrYkpUKzU3cmdjY0pYTlNCTEVkSlJ0cXJJTGdVS2dFRGhPQk1oMk1WK0NHTWVVTGFuNzd3ZU5sdy85M002VHkzRUtaTFZnU2tIS1ZuallnOFdLQzhuUHA0L3kyN2tnZVBteXdadFZJR0lqckdoWkoyMURESVQ1bXExS09wZ1hKRkJGZEt5WGFwOXlDbDNVcmFVLzlrQVh4R1FIdUtOSzZ4SUlBWk02bDRBYVI4dU1yTnUzaGJUUDJwT2dHK3ZMN2VSbUl4VGZpZVN0VkFnVUFvWEF1WUJBZmozMHNZOTk3TUxtZGRrWjBtOXlyTE83NVVHd3NsL0hxbzM3WEJNRWFkazkwakFteTZ0N2JOdEVNdXovWVIrTGNlbHI5eWhQUWExMHhqcXBDTVE2YU0zTWExbVJKVFJXTVlodzluT3ZsT3p5SGdXV0FObW4vS2pTdWdSQ2ZpUkJldVl6bnpsRmFGdldZd2M3blJiaDBlbVFJQ3N6Uk52YlVNcHZabFFxQkFxQlF1QmNRc0J1amp6TVpDR0RrYXpNRHBoV1BCeFZRaEwyK3IwS01uelZIaXpxMG4vOWRNY0F6SW81UzZydEZrdVdJeFlNd25WU0VZaDEwSnFaMXpwaGE1MlQ4b3VTeXk5V0ovTUNqaXF0U3lCc0ZJVWtQT01aejloVnBhelZ0dlNxVWlGUUNCUUNoY0NGQ0ppbVpoeU9TMGJ6bzNwK2JQQW9rcWtKejdSTWMweDIyN1EwZHErOUwyemdoaXhrNjJvYmpNbHZxMi9sK1J2MTFsajJYdWZiUUNDMmJoV0daV3g5ZjRUK1BpNU1PZSt4RUxrMEhVWHgrbjMyVFVtQ2JnVGwzT01lOTVnQ2N2cmE0V2FaMGgzdWNJZXBpcjN6YlVwVnF4NkZRQ0ZRQ0J3ckFqMFdiRnI5WVBub3VHUzBiekRWeVBxK05mVzBYUEt3SzJsMVUvOUJ3V2sxUmQ5WnRQV053VnIvTFo0cE1OSVNWb0dTcTFJM0RwdVZkWjFnVEY4TCtMU2k3dm5QZi82MElxWlB3MHp5ZnRXOTIzeHQ2MVpoV0Y0akdyWjdJcVpsTkphdjlTMWpXOThoYkhwNWxrQmFZa05CUCt0Wno5cVlkMk10ZFEvc25PclRnMnVtZlI0c0M3SkdXT3EvY1RBZDYxOGhVQWdVQXVjNkFsYlQ5Ui8xYS9hMldFNzJPM25UbTk2MGZQblFQdmZwOE5aL3lLL1pqOGMrUGQvN3ZkODdHWDBqa1ZsK21MMTk3TnZUcDFxbTVhNVdaYnoydGErZDJrQVgyY2ZpSkthdEl4RFlZTitlZENJSWxHOFBvR3gzdWN0ZFdnOXlhWDNyMFltVldnYnAzS1pONnlicmtDM1YyUzlaM29NSXpFM1dCMXNhWkQxd243Wm9mWjV0V21yYWYvcTEyWERHT3VOS2hVQWhVQWdVQXEzMWxSalRjdVh1M2o5bGJ4TWJkdGtiNXlnVHVleHZUckpjczYvTWFMd2paSHNTTHdxNTMxZVFGSUVJS0p0dzdNRTB6ZCtZYk5ERXJkVi90cmIxZmNtbnZTREc3K2VlMjR2aHhTOSs4YjdadWJMc05yWk93bUR0Y0ZhcEVDZ0VDb0ZDWUc4RVRGWGJSSS9ybjNkNVRIWjg3TDkxY1FxeEdQT2N6ZlArT3lUVDFJYmptSkFjaG1ML3FlOW1wOHFUbUxiT0EzRzZsMkRUanY1REw2ZkxzdTkzZlcvejVtKy9wTE9jdEcxSjkydHpmVjhJRkFLRndObEF3SmJzejN2ZTgxb1BQbSsyNVA3UkgvM1JhUU8rL2d1WTB3Wk5mU1hiMmFqR3JHZllFZmE4ODg1Ym1iY0hRazRiWTYzODhnUmMzTG9neWhPQWVUV2hFQ2dFQ29GQ1lCOEVCTUVMWExRTDcvM3VkNzhtcUxIL1hIYnJ2d2k2WnpEalBrVWV5ZGZxMlpkeHJpejd6VzkrYyt0TFVWZCtkeEl1bmlnUHhFbDRJZFdHUXFBUUtBUUtnUXNSRUFzaENIR1RreDlEOURzaFl1NzY4dEtkcWdxc3ROMDhyOGxKVFZ0SElQcEdIOU1LaGprdnBPOUlPZjE0MVp5OGxhY1FLQVFLZ1VLZ0VGZ1hBZE10Z2lldEdQR0RpWmJuQy9BWGsrZDNOUG9PbXVzV3VUWDV0NDVBUE9FSlQ1aFdNbUIzQW15c3Y5MHJXWWRicVJBb0JBcUJRcUFRT0VvRWVFcjhrSmFmT3JkUHhXVXVjNWxwMmY1dGJuT2JvM3pzc1plOWRRU0NTOGd5UzJ1RUxaL3BXMWtmQzRpV1pGNXd3UVd0LzdqTDJzOC8vL3p6cDkrT0gzOTFjKzFDVHRBTmdwQkVYZmNmRnp0QnJUcDRVL3ArLzVOTDFLLzZWV3JOeXFpKzgrdjBWM2kwWmhranE5ZlN3VXB0aW9tZ3dPbUc0MDVrdWoyS3BMZTk3VzN0eVU5KzhvR3JKUDVqMDlORmJLTzU2WlZjVlQ4N2hEM2lFWStZWHBMNXA3T2QrZzljTlVUQVFGNDNQZVVwVDVsK3JyWUl4SVhJMlJTbS96QmFFWWhQZGFUOGJISHREWEloSUg3ZTJaSTRhK29ydGVubm9aSHQvaHNMQlVkSEFLSHF2NWR4eGl2d05nM01hMXpqR3ROK1JudnRmcmtKOWQxYUFzSDc4SktYdkdSU3hINURmcHVTL1NOc1FuVzZuYzIycVQxbldsZmt3WTZpMW5kWGFwTWw5WmpIUEdiV2N1SnpBUzlyL205M3U5dTEvcnNDNTBKejkyM2pBeDd3Z0NteTN3NjhsVnA3L09NZlArMFl5YWlzZEhZUldOOThQcnYxMi9OcFdKbXRReXNWQW9WQUlWQUlGQUtGd05sSFlPOEl4TE5mbDNwaUlWQUlGQUtGUUNGUUNHd0pBa1VndHVSRlZUVUxnVUtnRUNnRUNvRk5RcUFJeENhOWphcExJVkFJRkFLRlFDR3dKUWdVZ2RpU0YxWFZMQVFLZ1VLZ0VDZ0VOZ21CSWhDYjlEYXFMb1ZBSVZBSUZBS0Z3SllnVUFSaVMxNVVWYk1RS0FRS2dVS2dFTmdrQklwQWJOTGJxTG9VQW9WQUlWQUlGQUpiZ3NEV2JpUzFKZml1ck9iclgvLzYyb2x5UU9ZZi8vRWYyeGQ5MFJmVlRwU2Z3dVJmL3VWZjJsV3VjcFYyNlV0ZmVrRHAzRDE5eHp2ZU1lMUNXVHRSWHRnSDN2V3VkMDFqcFhhaXZCQVBPMUYrNGhPZm1NYk11VHRLanFmbFJTQ09CL2Q2YWlGUUNCUUNoVUFoc05VSTFCVEdWcisrcW53aFVBZ1VBb1ZBSVhBOENCU0JPQjdjNjZtRlFDRlFDQlFDaGNCV0kxQUVZcXRmWDFXK0VDZ0VDb0ZDb0JBNEhnU0tRQndQN3ZYVVFxQVFLQVFLZ1VKZ3F4RW9BckhWcjY4cVh3Z1VBb1ZBSVZBSUhBOENSU0NPQi9kNmFpRlFDQlFDaFVBaHNOVUlGSUhZNnRkWGxTOEVDb0ZDb0JBb0JJNEhnU0lReDRON1BiVVFLQVFLZ1VLZ0VOaHFCSXBBYlBYcnE4b1hBb1ZBSVZBSUZBTEhnMEFSaU9QQnZaNWFDQlFDaFVBaFVBaHNOUUpGSUk3aDlTMFdpMk40NnZFODhwT2YvT1MrRDU2RHg1dzgrejVvU3pMTWFldWNQRnZTM0xaZlcvYjdYanZuNU5rR1BHcTh0UGFSajN6a3RLOXF6cnMrckR5bnJVaDkyWXBBbk1WTzhLdS8rcXZ0NWplLytmUWpTVi8xVlYvVkxyamdnclA0OUxQM3FBOS8rTVB0QVE5NFFMdnFWYS9hTG43eGk3Y3YvTUl2YkQvNWt6L1ovdmQvLzNkWEplYmdNU2ZQcmtLMzRNUDk3bmUvZHFVclhlbVVtczVwNjV3OHB4UzhnUmYrNHovK285Mys5cmR2bi9NNW45T3VjWTFydEIvNWtSOXA3M3puTzNmVjlMV3ZmVzI3MDUzdTFDNS8rY3UzYTEzcld1MVJqM3JVcnU5OU9DbDR2UENGTDJ3M3VNRU4ybWQ4eG1lMEsxN3hpdTMrOTc5L000N0dOQWVQT1huR01qZnQvSmQvK1pmYlhqOFNOdWRkNzVmblF4LzZVSHZ3Z3gvY3JuM3RhN2NyWE9FS1V4OTh6M3ZlczJrd2JFOTlPbE9yZEJZUWVQR0xYN3o0Zi8vdi95MmU4cFNuTEY3M3V0Y3Q3bjN2ZXk4dWVjbExUdWRuNGZGbjlSRjN2dk9kRjEzb0x4N3ptTWNzWHZXcVZ5MSsvTWQvZk5HSnhIUk1SZWJnTVNkUHl0dVdZeWVOaTR0YzVDS0x6L3U4ejl0VjVUbHRuWk5uVjZFYitxRmJtSXVyWC8zcWk1dmU5S2FMdi9pTHYxajg5bS8vOXVKTHZ1UkxGcDBzN05TNEs4OUZKdzJMTzk3eGpvdXVGQmZubjMvK292ODY2ZUluZnVJbmR2S2NGRHplOElZM0xEcHhXTnoydHJkZHZPeGxMMXM4N1dsUFczejJaMy8yNHU1M3YvdE9XK2ZnTVNmUFRvRWJlUEo3di9kN2s0eTgxS1V1ZFVydDVyenJPWG51ZTkvN0xyNzRpNzk0OGFJWHZXangwcGUrZE5GSjIrSXJ2dUlyRnQzemM4b3o2OEwrQ0hEOVZUb0xDRnpuT3RmWkpTQTk4c3UvL01zWGQ3dmIzYzdDMDgvZUk5NzN2dmN0TG5yUml5NjZSYm5yb2QvNW5kKzVTMm5Pd1dOT25sMFAyZkFQSC96Z0J4Zlh2T1kxRjllNzN2VjJZYUhhYzlvNko4K0dRekJWNzVkKzZaY21ndm12Ly9xdk85Vjkvdk9mUDVHSzdwbVlyajNzWVErYmxDaXlrWVE4ZE90MDhkR1BmblM2ZEZMdytLbWYrcW1KUVBTZnBVNVRGL2U1ejMwV24vbVpuN240di8vN3YrbmFIRHptNU5sNXdBYWRrQm1JWWplN0YxLzZwVis2V0VVZzVyenIvZkw4M2QvOTNTU2IvdUFQL21DbjlXOTg0eHVuNS83Sm4vekp6clU2bVk5QVRXR2NCV2ZSdi8zYnY3WGVVZHZ0Ym5lN1hVLzdqdS80anZiSGYvekh1NjV0KzRjdThGcTNvTm9QL3VBUDdtcEtWNXl0SzlCbWpuY09IblB5N0hyQUZueDQwSU1lMUs1NzNldTJPOXpoRHJ0cU82ZXRjL0xzS25TRFAvemFyLzNhaE1IVnJuYTFuVnJlK3RhM2J1OTR4enQycG5hNDlHOTV5MXUyN3FYYnlmUHQzLzd0clN2Wjl1cFh2M3BXSDlxNWNjTlBUT044NGhPZmFQL3pQLyt6VTFQVGZaLzFXWi9WdXJkcXVyWWZIakxOeWJQemdBMDZlYzFyWHRPNjU2WDkvdS8vZnJ2WHZlNjEwK1pVY1U3Zm41T25leDFhOXdLM1c5M3FWaW02ZmRtWGZWbnIzcThUSjRkM0duakVKMFVnamhoZ3hmL3pQLy96OUpUUC8velAzL1UwTVFMLzlWLy9OU25WWFY5czhRZnppdmU4NXowYndwQ0VOSFEzZFJQMzBiMFRzL0E0YVpnUlhyLzFXNy9WbnY3MHB3ZVduZU9jdHM3SnMxUGdocDhnQ3RlLy92WGI3Lzd1NzdiYjNPWTI3YXUvK3F0YnQ4SWI4cG1rdlNQQmNEM2pSL3pFU2NMajI3N3QyOW9YZk1FWHRPLy8vdTl2Zi83bmY5NmU4SVFudE4vOHpkOXMzUXV4bzB6M3d3TStjL0xJdDJucGhqZThZWHZ6bTkvYytoVE95cXJOZWRkejh2elRQLzNURkYrQ1JJeUpISDczdTk4OVhxcnptUWdVZ1pnSjFKbGsrOEFIUGpEZHp0SVlrK0F3UXZPa0IvRTg5S0VQblFMa0h2dll4MDdObjRQSG5Ed2pscHQ4enZQUzU3UGJULy8wVDUraUZOVjdUbHZuNU5sa0RGSzM3aHh0Q01Cem4vdmMxbU5scGlES2kxM3NZdTNIZnV6SDJsM3ZldGRrbXpCQlJzZDB1Y3RkYnZyNG4vLzVuN013RysvZDVQT3JYT1VxN1RuUGVVN3I4U0R0bTc3cG05b1AvL0FQdDYvLytxK2ZNRW05dmYvVDRTSGZuRHdwYjVPT2w3M3NaYWZnMGIzcU5LZnZ6OGxqSEM1ajZKbmtjQkdJdmRBLy9mVWlFS2ZINTFDK3RSSkJZbjJQS1o4Ly92R1BqNWRQMVBuUC91elBUdGJsb3gvOTZNblMxTGc1ZU16SnN5MUFXWkhDSThNenN5ck5hZXVjUEt2SzNyUnJQWDZoNmU4czdSNU1QSzJpZVBuTFg5NTZvRzM3OVYvLzlXWVZnYVM5aU1XWXVMZWlrYjhBQUF3dlNVUkJWUFA5ZmV4akg1dlZoOFo3Ti9uOEQvL3dEOXN0Ym5HTGFjWEpYLzNWWDdWZitJVmZhSzkvL2V1YmFaMTRaZmJEUS92bTVObGtIUGFxMjV5K1B5ZVAvaFNaT3o1TG56ckpNbmhzNjJHZjc5Wm9oMTE2bFRjaGNPVXJYM2s2dnZlOTc5MkZTRDVmNWpLWDJYWDlwSHpnZVREdi84aEhQckk5NUNFUDJXbldIRHptNU5rcGNJTlBXSlhQZk9Zekp3OUVYNUhTWHZuS1YwN3o5K2E4bmIvclhlOXFjOW82Sjg4R3c3QlR0UjRnMS9UM205M3NacTBIek8xYzcwRjAwN240QmtsN016Nm1DLzFmRDdhYjludm9LeFJtWVpiN052MzQxS2MrdGZXVkFhMnZOR2xmOHpWZk0wMWRQTzV4ajJ0LytxZC9Pc1Y3cVA5K2VNek5zK2xZcktyZm5MNC9KdzlQejNLZjhqejlTcCtxdEQ0Q0Y1ckc2OTlYZDZ5QlFEcjNzcHZNWnk2MWs5aDVrUWQ3UC96OHovLzh0S1o5aEdzT0huUHlqR1Z1NnZuZi9NM2ZURXFQdTM0NVVSWS84ek0vTTFtZXZqdGQvemdwZUdpbk9XZjdPb3hKdkFQck1CWTNZYjhLRC9mdzVwd2tQQVFROGxLTlNXeklKUzV4aWZhU2w3eGs4dHp0aDRkNzUrUVpuN0V0NTNQZTlkdzhnbkRGWkkyZUNQM3NhNy8yYTdjRmpvMnFaM2tnenNMck1MQkYrL2FsUXJ1ZVpnWEdlZWVkdCt2YVNmandwQ2M5YVNJUE5vV3hJYzV5bW9QSG5Eekw1VzdpWjdFUC8vQVAvN0RyVDNDY2VCalgrekxlU2ZEdjF6OU9DaDdlMGMxdmZ2UEdWVDl1TE1iYUp0ajczaERUYStUU2Y4RUxYckFyd05qNDZVc2IyNDF1ZEtOWm1HMWlmMWhWSjhHaGdnakg5TmQvL2RmVHlnenZYZG9QajdsNXBzSzI3Titjdmo4bkR3eHRKTlgzZjloQjRPMXZmL3MwRGsraUhONXA1RkdlekYveFdUblBCSUVuUC9uSjA3cnU1ejN2ZVl1K1hHdlJJNjJuamFTNjREaVRZamZ1M24vLzkzOWY5T1ZuaTV2YzVDYUxIa2wreWw5MzNVOTFub1BIbkR3YkI4Q01DdlVwblZQMmdaalQxamw1Wmp6KzJMTzg2VTF2V3ZUNTZNVTk3bkdQUlErSVhOaGN5MlkrTnBaSy8rakw4cWJOeHg3NHdBY3U3Si94aWxlOFl0RjM3MXo4M00vOTNFNzlUd29lWkVHZmg1ODJtZXZCZ0l1Ly9NdS9YUFFwbmtVbkZvdnVjcC9hT3dlUE9YbDJ3TnZRazhjLy92SFRobUhMMVp2enJ1Zms2VVJoMFFubzRxMXZmZXZVOS9xU3prWDNCTlpHVXN1QXoveGNHMG5OQk9wTXN4R00zUnFmaENKaFlkTVR1K3VkdFBURUp6NXgycGlsazk2VngvZS8vLzFUaytmZ01TZlBOdUszaWtETWFldWNQTnVDaDUwQSs5TEZTWEgyQUxoRnR3NFhmVW56cnVyM2xScUw3cW1aOHZTcHZrVVBRbDEwcjhWT25wT0NSNSsybVhiWXRJRVMyV0RzM1BqR04xN1krR2hNKytFaDc1dzhZNW1iZHI0WGdaanpydWZrNlI2SFJWODJQR0hjcDRnV2ZkWExvbnNDTncyR3JhblBSZFQwS0QwY1ZmWnVCRVNoVzRabTNYZWwxdWJnTVNmUFNjRnlUbHZuNU5rV1BHd0FKQVpvcnpnZzR1bHRiM3RiNjF0Zjc2eThXRzdiU2NGRC9FZTNqS2U0cUZYTERiVjdEaDV6OGl4anVDMmY1N3pyT1huc3YyTlZ4bDQ0YndzZXgxM1BJaERIL1FicStZVkFJVkFJRkFLRndCWWlVRUdVVy9qU3FzcUZRQ0ZRQ0JRQ2hjQnhJMUFFNHJqZlFEMi9FQ2dFQ29GQ29CRFlRZ1NLUUd6aFM2c3FGd0tGUUNGUUNCUUN4NDFBRVlqamZnUDEvRUtnRUNnRUNvRkNZQXNSS0FLeGhTK3RxbHdJRkFLRlFDRlFDQnczQWtVZ2p2c04xUE1MZ1VLZ0VDZ0VDb0V0UktBSXhCYSt0S3B5SVZBSUZBS0ZRQ0Z3M0FnVWdUanVOMURQTHdRS2dVS2dFQ2dFdGhDQkloQmIrTktxeW9WQUlWQUlGQUtGd0hFalVBVGl1TjlBUGI4UUtBUUtnVUtnRU5oQ0JJcEFiT0ZMcXlvWEFvVkFJVkFJRkFMSGpVQVJpT04rQS9YOFFxQVFLQVFLZ1VKZ0N4RW9BckdGTDYycVhBZ1VBb1ZBSVZBSUhEY0NSU0NPK3czVTh3dUJRcUFRS0FRS2dTMUVvQWpFRnI2MHFuSWhVQWdVQW9WQUlYRGNDQlNCT080M1VNOHZCQXFCUXFBUUtBUzJFSUVpRUZ2NDBxcktoVUFoVUFnVUFvWEFjU05RQk9LNDMwQTl2eEFvQkFxQlFxQVEyRUlFaWtCczRVdXJLaGNDaFVBaFVBZ1VBc2VOUUJHSTQzNEQ5ZnhDb0JBb0JBcUJRbUFMRVNnQ3NZVXZyYXBjQ0JRQ2hVQWhVQWdjTndKRklJNzdEZFR6QzRGQ29CQW9CQXFCTFVTZ0NNUVd2clNxY2lGUUNCUUNoVUFoY053SUZJRTQ3amRRenk4RUNvRkNvQkFvQkxZUWdTSVFXL2pTcXNxRlFDRlFDQlFDaGNCeEkxQUU0cmpmUUQyL0VOaGdCRjcvK3RlM2kxemtJdTA1ejNuT0dkZnlZaGU3V0h2NjA1OSt4dVZVQVlWQUliQVpDQlNCMkl6M1VMVW9CQXFCUXFBUUtBUzJDb0VpRUZ2MXVxcXloVUFoVUFnVUFvWEFaaUJRQkdJejNrUFZvaERZR2dUT08rKzg5c0lYdnJEZDk3NzNiVmUvK3RXbnZ3Yys4SUh0RTUvNHhFNGIzdjcydDdlNzNlMXU3Y3BYdm5LNzBZMXUxUDdzei81czU3dWNmUGpESDI3M3Z2ZTkyeld2ZWMxMnhTdGVzZDMydHJkdDczakhPL0oxdTg5OTd0TTg2NE1mL09ET3RVYzk2bEh0Njc3dTY5cC8vL2QvNzF5cmswS2dFRGdlQklwQUhBL3U5ZFJDWUdzUmVOM3JYdGZ1ZnZlN3Q5ZTg1alh0SVE5NVNMdlZyVzdWSHZlNHg3VW5QdkdKVTVzKy92R1B0Ky82cnU5cXIzNzFxOXVUbnZTa2RwZTczS1hkOFk1M2JKLzg1Q2QzMnJ4WUxObzNmdU0zdHQvNW5kOXBkN3JUbmRyVG52YTA5cDczdktmZDVDWTNhZTk5NzN1bmZNakZLMS81eXZhd2h6MXMrdXo4RVk5NFJMdjk3Vy9mUHZkelAzZW5yRG9wQkFxQjQwSGc0c2Z6MkhwcUlWQUliRE1DVjdyU2xkckxYdmF5S2NCU08vNys3LysrdmVBRkwyZzhFZWVmZjM1RE10N3lscmRNM2duZlgrRUtWMmpmOHozZjQzUktpQU5DOEx6blBhOTk2N2QrNjNUdDFyZSs5ZVNKUUVZZS9laEh0K3RlOTdvVGVYajR3eDgra1l5NzN2V3VrL2ZoaDM3b2h6NVZTaDBLZ1VMZ09CRW9EOFJ4b2wvUExnUzJGSUZiM09JV08rUkJFNjU5N1d1M0QzemdBMU5ya0ljYjMvakdPK1RCeFR2YzRRN3RvaGY5dExoNXlVdGUwaTU3MmN0T2hPRnYvL1p2bTc4M3Z2R043U3UvOGl2YnkxLys4cWtjL3g3ODRBZTM2MS8vK3UwYnZ1RWIyanZmK2M2Sm5GZ1ZVcWtRS0FTT0g0SHlRQnovTzZnYUZBSmJoNENZaFRGZDhwS1gzSm1pZVBPYjM5eDRLTVowaVV0Y1lpSUx1ZmEydDcydHZmLzk3MjgzdmVsTmMybm5lSTFyWEdQbi9PSVh2M2g3MElNZU5FMkI4R0NNMysxa3FwTkNvQkE0RmdRK2JSSWN5K1Byb1lWQUliQ05DSnpPQzNDMXExMnR2ZTk5N3p1bFdZSW1reTUzdWN0TlpPQkRIL3BRYzMzOGU4TWIzcEJzN2FNZi9XZ1RPSG5WcTE2MVBmdlp6MjZ2ZXRXcmRyNnJrMEtnRURoZUJJcEFIQy8rOWZSQzRNUWhjSU1iM0dDS2dSaFhUeUFGeUVMUzlhNTN2Y1lMNGZxbEwzM3A2ZTlTbDdwVXUvLzk3OStlOFl4bkpOc1VBMkZGeDB0Zit0TEpXeUVnRTZtb1ZBZ1VBc2VQUUJHSTQzOEhWWU5DNEVRaDhOM2YvZDN0TXBlNVRMdm5QZTg1cmF5NDRJSUwycDN2Zk9kZGJielh2ZTdWTG4vNXkwK0V3WkpRS3pBZStjaEh0bC81bFY5cE43dlp6YWE4Z2l3RlZQSkFYT3RhMTJyUGZPWXpwOERNaHo3MG9idktxZytGUUNGd1BBZ1VnVGdlM091cGhjQ0pSVUQ4dzNPZis5d21Ga0tzeERkLzh6ZTNXOTd5bHRNMFJCcHRWWWE5SVQ3eWtZKzBiL21XYjVueS9kRWYvVkY3NmxPZk9nVmc4akx3TnR6d2hqZWNTSWI3cm5PZDYwekxSaC8vK01lM1Y3emlGU21xam9WQUlYQk1DRnlrcjhkZUhOT3o2N0dGUUNGd3doRjQ5N3ZmUFhralRGUHNsZXo3OExHUGZXemFkR3F2UEhXOUVDZ0VOZytCSWhDYjkwNnFSb1ZBSVZBSUZBS0Z3TVlqVUZNWUcvK0txb0tGUUNGUUNCUUNoY0RtSVZBRVl2UGVTZFdvRUNnRUNvRkNvQkRZZUFTS1FHejhLNm9LRmdLRlFDRlFDQlFDbTRkQUVZak5leWRWbzBLZ0VDZ0VDb0ZDWU9NUktBS3g4YStvS2xnSUZBS0ZRQ0ZRQ0d3ZUFrVWdOdStkVkkwS2dVS2dFQ2dFQ29HTlI2QUl4TWEvb3FwZ0lWQUlGQUtGUUNHd2VRZ1VnZGk4ZDFJMUtnUUtnVUtnRUNnRU5oNkJJaEFiLzRxcWdvVkFJVkFJRkFLRndPWWhVQVJpODk1SjFhZ1FLQVFLZ1VLZ0VOaDRCSXBBYlB3cnFnb1dBb1ZBSVZBSUZBS2JoMEFSaU0xN0oxV2pRcUFRS0FRS2dVSmc0eEVvQXJIeHI2Z3FXQWdVQW9WQUlWQUliQjRDUlNBMjc1MVVqUXFCUXFBUUtBUUtnWTFIb0FqRXhyK2lxbUFoVUFnVUFvVkFJYkI1Q0JTQjJMeDNValVxQkFxQlFxQVFLQVEySG9FaUVCdi9pcXFDaFVBaFVBZ1VBb1hBNWlGUUJHTHoza25WcUJBb0JBcUJRcUFRMkhnRWlrQnMvQ3VxQ2hZQ2hVQWhVQWdVQXB1SFFCR0l6WHNuVmFOQ29CQW9CQXFCUW1EakVTZ0NzZkd2cUNwWUNCUUNoVUFoVUFoc0hnSkZJRGJ2blZTTkNvRkNvQkFvQkFxQmpVZmcvd05vK3dwNG5QMTBDd0FBQUFCSlJVNUVya0pnZ2c9PVwiIC8+XG5cbjwhLS0gcm5iLXBsb3QtZW5kIC0tPlxuIn0= -->


<!-- rnb-plot-begin -->

<img src="data:image/png;base64,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" />

<!-- rnb-plot-end -->


<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVjM1J5S0dsdVpteGhkR2x2YmlsY2JtQmdZQ0o5IC0tPlxuXG5gYGByXG5zdHIoaW5mbGF0aW9uKVxuYGBgXG5cbjwhLS0gcm5iLXNvdXJjZS1lbmQgLS0+XG4ifQ== -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuc3RyKGluZmxhdGlvbilcbmBgYCJ9 -->

```r
str(inflation)
str(unemployment)
str(google_trends)
str(rain)
str(temp) # this has NaNs, must fill somehow

Sales

Sales Monthly

# sales
## sales monthly
df_sales_m <- sales %>%
  mutate(month = floor_date(date, "month")) %>% # Extract month
  group_by(month) %>%
  summarise(sales_m = sum(sales_cop), bar_m = sum(bar), food_m = sum(food)
            )     # Summing values

head(df_sales_m)

Sales Weekly

# sales
## sales monthly
df_sales_m <- sales %>%
  mutate(month = floor_date(date, "month")) %>% # Extract month
  group_by(month) %>%
  summarise(sales_m = sum(sales_cop), bar_m = sum(bar), food_m = sum(food)
            )     # Summing values

head(df_sales_m)

FX

## sales weekly
df_sales_w <- sales %>%
  mutate(week = floor_date(date, "week")) %>% # Extract month
  group_by(week) %>%
  summarise(sales_w = sum(sales_cop), bar_w = sum(bar), food_w = sum(food))     # Summing values

head(df_sales_w)

Rain

# google trends

# montly
df_google_m <- google_trends %>%
  mutate(month = floor_date(date, "month")) %>%
  group_by(month) %>%
  summarise(google_m = mean(google_trends))


# weekly
df_google_w <- google_trends %>%
  mutate(week = floor_date(date, "week")) %>%
  group_by(week) %>%
  summarise(google_w = mean(google_trends))

head(df_google_m)
head(df_google_w)

Temperature

## rain
df_rain_g = rain %>%
  group_by(date, region) %>%
  summarise(rain_sum=sum(contribution_m3s))
`summarise()` has grouped output by 'date'. You can override using the `.groups` argument.
df_rain_g  <- df_rain_g[df_rain_g$region=="ANTIOQUIA",]

head(df_rain_g)

# montly
df_rain_m <- df_rain_g %>%
  mutate(month = floor_date(date, "month")) %>%
  group_by(month) %>%
  summarise(rain_m = sum(rain_sum))


# weekly
df_rain_w <- df_rain_g %>%
  mutate(week = floor_date(date, "week")) %>%
  group_by(week) %>%
  summarise(rain_w = sum(rain_sum))

head(df_rain_m)
head(df_rain_w)

Merging Data Frames

Daily Data

Weekly Data

Monthly Data

EDA

objects_to_keep <- c("df_merged_d", "df_merged_w", "df_merged_m")
# Remove all objects except those specified
rm(list = setdiff(ls(), objects_to_keep))

Daily Sales

Weekly sales

Monthly sales

Stacked bar plots

We want to move to a stacked bar chart when we care about the relative decomposition of each primary bar based on the levels of a second categorical variable. Each bar is now comprised of a number of sub-bars, each one corresponding with a level of a secondary categorical variable. The total length of each stacked bar is the same as before, but now we can see how the secondary groups contributed to that total.

One important consideration in building a stacked bar chart is to decide which of the two categorical variables will be the primary variable (dictating major axis positions and overall bar lengths) and which will be the secondary (dictating how each primary bar will be subdivided). The most ‘important’ variable should be the primary; use domain knowledge and the specific type of categorical variables to make a decision on how to assign your categorical variables

#Monthly
# Reshape the data to a long format
df_sales_m_long <- df_merged_m %>%
  pivot_longer(cols = c(bar_m, food_m), names_to = "Category", values_to = "Value")

# Create the stacked bar plot
ggplot(df_sales_m_long, aes(x = month, y = Value, fill = Category)) +
  geom_bar(stat = "identity", position = "stack") +
  ggtitle("Monthly Sales of Restaurant") +
  labs(y = "Sales", x = "Month", fill = "Category") +
  theme_minimal()
df_sales_w_long <- df_merged_w %>%
  pivot_longer(cols = c(bar_w, food_w), names_to = "Category", values_to = "Value")

# Create the stacked bar plot
ggplot(df_sales_w_long, aes(x = week, y = Value, fill = Category)) +
  geom_bar(stat = "identity", position = "stack") +
  ggtitle("Weekly Sales of Restaurant") +
  labs(y = "Sales", x = "Week", fill = "Category") +
  theme_minimal()

Seasonal plots

# Seasonal plots
df_sales_w_filtered <- df_merged_w %>%
  filter(week >= ymd("2021-12-31"))


tseries_w <- ts(df_sales_w_filtered$sales_w , start = c(2022, 1), frequency = 52)
head(tseries_w)
Time Series:
Start = c(2022, 1) 
End = c(2022, 6) 
Frequency = 52 
[1]  5654618  5894371  8308052  9164178 11934123
[6]  9777570
seasonplot(tseries_w, col = rainbow(3), year.labels = TRUE, main = "Seasonal Plot")
text(x = 1, y = max(tseries_w) - 1.5e7, labels = "2024", col = "blue")

NA
NA
# seasonplot monthly
df_sales_m_filtered <- df_merged_m %>%
  filter(month >= ymd("2021-12-31"))


tseries_m <- ts(df_sales_m_filtered$sales_m , start = c(2022, 1), frequency = 12)
head(tseries_m)
          Jan      Feb      Mar      Apr
2022 31953282 41926179 37466677 57926246
          May      Jun
2022 79622843 88816435
seasonplot(tseries_m, col = rainbow(3), year.labels = TRUE, main = "Seasonal Plot")
text(x = 1, y = max(tseries_m) - 1e6, labels = "2024", col = "blue")

Density

# Montly Density
# Select the columns of interest
variables <- c("sales_m", "bar_m", "food_m", "rain_m", "fx_m", "google_m",
               "ise", "inflation", "unemployment", "temp_m", "prcp_m")


# Transform the data to long format for ggplot2
df_long_m <- df_merged_m %>%
  pivot_longer(cols = all_of(variables), names_to = "Variable", values_to = "Value")

# Create the grid of density plots
ggplot(df_long_m, aes(x = Value)) +
  geom_density(fill = "blue", alpha = 0.4) +
  facet_wrap(~ Variable, scales = "free", ncol = 3) +
  labs(title = "Density Plots of Selected Variables",
       x = "Value", y = "Density") +
  theme_minimal()

# Weekly Density
# Select the columns of interest
variables <- c("sales_w", "bar_w", "food_w", "rain_w", "fx_w", "google_w",
                "temp_w", "prcp_w")



df_long_w <- df_merged_w %>%
  pivot_longer(cols = all_of(variables), names_to = "Variable", values_to = "Value")

# Create the grid of density plots
ggplot(df_long_w, aes(x = Value)) +
  geom_density(fill = "blue", alpha = 0.4) +
  facet_wrap(~ Variable, scales = "free", ncol = 3) +
  labs(title = "Density Plots of Selected Variables",
       x = "Value", y = "Density") +
  theme_minimal()

# Daily Density

# Select the columns of interest
variables <- c("sales_cop", "bar", "food", "rain_sum", "fx", 
               "tmedian", "prcp")



df_long_d <- df_merged_d %>%
  pivot_longer(cols = all_of(variables), names_to = "Variable", values_to = "Value")

# Create the grid of density plots
ggplot(df_long_d, aes(x = Value)) +
  geom_density(fill = "blue", alpha = 0.4) +
  facet_wrap(~ Variable, scales = "free", ncol = 3) +
  labs(title = "Density Plots of Selected Variables",
       x = "Value", y = "Density") +
  theme_minimal()

Covariates

### 3.5.1 economic variables-----------------------
# economic growth
ggplot(df_merged_m, aes(x=month, y=ise)) +
  geom_line() + ggtitle("Monthly activity in Colombia")

# clearly seasonal and trend

# fx
ggplot(df_merged_d, aes(x=date, y=fx)) +
  geom_line() + ggtitle("Daily COP/USD")

# trend but no clear seasonality

# inflation
ggplot(df_merged_m, aes(x=month, y=inflation)) +
  geom_line() + ggtitle("Monthly inflation National")

# business cycles, no tend or seasonality

# unemployment
ggplot(df_merged_m, aes(x=month, y=unemployment)) +
  geom_line() + ggtitle("Montly trailing unemployment Medellin")

# seasonal and trend downwards


### 3.5.2 Other variables

# google trends
ggplot(df_merged_w, aes(x=week, y=google_w)) +
  geom_line() + ggtitle("Weelkly Google trends 'Restaurantes'")

# no clear behaviour, drop in pandemic

# rain
ggplot(df_merged_d, aes(x=date, y=rain_sum)) +
  geom_line() + ggtitle("Daily rain approximated in Antioquia")

# no trend or seasonality clearly

# temperature
ggplot(df_merged_d, aes(x=date, y=tmedian)) +
  geom_line() + ggtitle("Daily Median temperature in Medellin")


# almost stationary

# temperature
ggplot(df_merged_d, aes(x=date, y=tavg)) +
  geom_line() + ggtitle("Daily Average temperature in Medellin")



# this one looks weird, better keep working on median

# precipitation from temp
ggplot(df_merged_d, aes(x=date, y=prcp)) +
  geom_line() + ggtitle("Daily  precipitation in Medellin")

# looks decent

Pairplots

df_merged_d <- subset(df_merged_d, select = -region)

# daily
ggpairs(df_merged_d, 
        columns = 2:8)

# sales have correl with fx and rain_sum
# weekly
ggpairs(df_merged_w, 
        columns = 2:9)

# sales have correl with rain, google, fx, temp
# bar has more correl with temp

# montly
ggpairs(df_merged_m, 
        columns = 2:12)

Correlation Matrix

# Exclude 'date' column
numeric_df_d <- df_merged_d[, sapply(df_merged_d, is.numeric)]
cor_matrix_d <- cor(numeric_df_d, use = "complete.obs")  # Use only complete rows
cor_matrix_d
            sales_cop          bar        food
sales_cop 1.000000000  0.895118281  0.98135791
bar       0.895118281  1.000000000  0.79301917
food      0.981357913  0.793019172  1.00000000
rain_sum  0.166252448  0.127567019  0.17164822
fx        0.146774104  0.136714885  0.14261504
tavg      0.008884659  0.089640797 -0.02562481
prcp      0.028085504 -0.001337552  0.03913167
tmedian   0.108891610  0.111686146  0.10120437
            rain_sum          fx         tavg
sales_cop  0.1662524  0.14677410  0.008884659
bar        0.1275670  0.13671488  0.089640797
food       0.1716482  0.14261504 -0.025624811
rain_sum   1.0000000  0.63500919 -0.134005147
fx         0.6350092  1.00000000  0.164550220
tavg      -0.1340051  0.16455022  1.000000000
prcp       0.1857676  0.05556529 -0.267367632
tmedian   -0.2717930 -0.07710937  0.656170981
                  prcp     tmedian
sales_cop  0.028085504  0.10889161
bar       -0.001337552  0.11168615
food       0.039131672  0.10120437
rain_sum   0.185767588 -0.27179302
fx         0.055565287 -0.07710937
tavg      -0.267367632  0.65617098
prcp       1.000000000 -0.22103872
tmedian   -0.221038724  1.00000000
numeric_df_w <- df_merged_w[, sapply(df_merged_w, is.numeric)]
cor_matrix_w <- cor(numeric_df_w, use = "complete.obs")  # Use only complete rows
cor_matrix_w
             sales_w      bar_w      food_w
sales_w   1.00000000  0.8910033  0.98922211
bar_w     0.89100331  1.0000000  0.81506933
food_w    0.98922211  0.8150693  1.00000000
rain_w    0.29131607  0.2875652  0.27858415
google_w -0.44467552 -0.3551772 -0.45333238
fx_w      0.24395629  0.2873958  0.22038752
temp_w   -0.02746535  0.1275798 -0.07507291
prcp_w    0.17241188  0.1211778  0.18095801
             rain_w     google_w         fx_w
sales_w   0.2913161 -0.444675519  0.243956293
bar_w     0.2875652 -0.355177208  0.287395824
food_w    0.2785842 -0.453332380  0.220387520
rain_w    1.0000000 -0.107348280  0.662664730
google_w -0.1073483  1.000000000 -0.002777267
fx_w      0.6626647 -0.002777267  1.000000000
temp_w   -0.1062959  0.208497604  0.193152564
prcp_w    0.3289820 -0.251630474  0.107858510
              temp_w     prcp_w
sales_w  -0.02746535  0.1724119
bar_w     0.12757976  0.1211778
food_w   -0.07507291  0.1809580
rain_w   -0.10629590  0.3289820
google_w  0.20849760 -0.2516305
fx_w      0.19315256  0.1078585
temp_w    1.00000000 -0.3047876
prcp_w   -0.30478758  1.0000000
numeric_df_m <- df_merged_m[, sapply(df_merged_m, is.numeric)]
cor_matrix_m <- cor(numeric_df_m, use = "complete.obs")  # Use only complete rows
cor_matrix_m
                 sales_m       bar_m     food_m
sales_m       1.00000000  0.91772972  0.9930535
bar_m         0.91772972  1.00000000  0.8646613
food_m        0.99305351  0.86466133  1.0000000
rain_m        0.34590142  0.35781875  0.3316856
fx_m          0.26008119  0.33043881  0.2325461
google_m     -0.60141163 -0.43583265 -0.6306910
ise           0.14184921  0.09197376  0.1528346
inflation     0.24620155  0.41865460  0.1885633
unemployment -0.47774546 -0.35355440 -0.4999277
temp_m       -0.05360312  0.12366320 -0.1041492
prcp_m        0.28057040  0.20114717  0.2956418
                   rain_m         fx_m
sales_m       0.345901419  0.260081195
bar_m         0.357818748  0.330438807
food_m        0.331685570  0.232546131
rain_m        1.000000000  0.700900212
fx_m          0.700900212  1.000000000
google_m     -0.127328581 -0.016302700
ise           0.143925313  0.006203153
inflation     0.554477494  0.731585721
unemployment -0.314673431 -0.148857922
temp_m       -0.004770513  0.242855832
prcp_m        0.364914544  0.106392263
                google_m          ise  inflation
sales_m      -0.60141163  0.141849210  0.2462015
bar_m        -0.43583265  0.091973761  0.4186546
food_m       -0.63069104  0.152834568  0.1885633
rain_m       -0.12732858  0.143925313  0.5544775
fx_m         -0.01630270  0.006203153  0.7315857
google_m      1.00000000  0.093304022  0.1600715
ise           0.09330402  1.000000000 -0.1118127
inflation     0.16007149 -0.111812691  1.0000000
unemployment  0.42550422 -0.602525241 -0.1308017
temp_m        0.33976804 -0.190530186  0.5982503
prcp_m       -0.37823361  0.047259121  0.0657641
             unemployment       temp_m
sales_m      -0.477745462 -0.053603118
bar_m        -0.353554400  0.123663200
food_m       -0.499927664 -0.104149167
rain_m       -0.314673431 -0.004770513
fx_m         -0.148857922  0.242855832
google_m      0.425504221  0.339768042
ise          -0.602525241 -0.190530186
inflation    -0.130801728  0.598250278
unemployment  1.000000000 -0.007286939
temp_m       -0.007286939  1.000000000
prcp_m       -0.415992203 -0.280144464
                  prcp_m
sales_m       0.28057040
bar_m         0.20114717
food_m        0.29564181
rain_m        0.36491454
fx_m          0.10639226
google_m     -0.37823361
ise           0.04725912
inflation     0.06576410
unemployment -0.41599220
temp_m       -0.28014446
prcp_m        1.00000000
# Plot the Correlation Matrix
par(mfrow=c(1,1))
corrplot(cor_matrix_d, method = "color", type = "upper", tl.col = "black", tl.srt = 45)

corrplot(cor_matrix_w, method = "color", type = "upper", tl.col = "black", tl.srt = 45)

corrplot(cor_matrix_m, method = "color", type = "upper", tl.col = "black", tl.srt = 45)

Rain has stronger correlation than prcp, so we drop prcp to not repeat the same variable from two sources Also we drop average temperature because median temperature seems more trustworthy

# drop prcp beacuse they "are the same"
df_merged_m <- df_merged_m %>% select(-prcp_m)
df_merged_w <- df_merged_w %>% select(-prcp_w)
df_merged_d <- df_merged_d %>% select(-prcp)

# drop avg temp
df_merged_d <- df_merged_d %>% select(-tavg)
colnames(df_merged_d)
[1] "date"      "sales_cop" "bar"      
[4] "food"      "rain_sum"  "fx"       
[7] "tmedian"  
### drop everything not on use
objects_to_keep <- c("df_merged_d", "df_merged_w", "df_merged_m")
# Remove all objects except those specified
rm(list = setdiff(ls(), objects_to_keep))

Variable Transformation

POSIXct and POSIXlt Classes

Times and date-times are represented by the POSIXct or the POSIXlt class in R. The POSIXct format stores date and time in seconds with the number of seconds beginning at January 1, 1970, so a POSIXct date-time is essentially an single value on a timeline. Date-times prior to 1970, will be negative numbers. The POSIXlt class stores other date and time information in a list such as hour of day of week, month of year, etc. The starting year for POSIXlt data is 1900, so 2022 would be stored as year 122. Months also begin at 0, so January is stored as month 0 and February as month 1. For both POSIX classes, the timezone can be classified. While date-times stored as POSIXct and POSIXlt look similar, when you unclass them with the unclass() function, you can see the additional information stored within the POSIXlt data.

Date Class

Dates without time can simply be stored as a Date class in R using the as.Date() function. Both Dates and POXIC classes need to be defined based on how they formatted. When uploading time series data into R, date and date-time data is typically uploaded as a character class and must be converted to date or time class using the as.Date(), as.POSIXct() or as.POSIXlt() functions.

Monthly

# Vars for model
# Month
# Ensure the `month` column is in POSIXct format
df_merged_m$month <- as.POSIXct(df_merged_m$month)

# Create the numeric variable: an evenly increasing number
df_merged_m <- df_merged_m %>%
  arrange(month) %>%  # Ensure data is sorted by month
  mutate(numeric_month = row_number())  # Assign an increasing number

# Create the seasonal variable: the 12 different months as a factor
df_merged_m <- df_merged_m %>%
  mutate(seasonal_month = factor(format(month, "%B"), levels = month.name))  # Month names as ordered factors

Weekly

# Week
# Ensure the `week` column is in POSIXct format
df_merged_w$week <- as.POSIXct(df_merged_w$week)

# Create the numeric variable: an evenly increasing number
df_merged_w <- df_merged_w %>%
  arrange(week) %>%  # Ensure data is sorted by week
  mutate(numeric_week = row_number())  # Assign an increasing number

# Create the seasonal variable: the 12 different months as a factor
df_merged_w <- df_merged_w %>%
  mutate(seasonal_month = factor(format(week, "%B"), levels = month.name))  # Month names as ordered factors

Daily

# Day
# Ensure the `day` column is in POSIXct format
df_merged_d$date <- as.POSIXct(df_merged_d$date)

# Create the numeric variable: an evenly increasing number
df_merged_d <- df_merged_d %>%
  arrange(date) %>%  # Ensure data is sorted by day
  mutate(numeric_day = row_number())  # Assign an increasing number
# Create the seasonal variable: the 12 different months as a factor
df_merged_d <- df_merged_d %>%
  mutate(seasonal_month = factor(format(date, "%B"), levels = month.name))  # Month names as ordered factors

# Create a column indicating the day of the week
df_merged_d <- df_merged_d %>%
  mutate(day_of_week = factor(weekdays(date), levels = c("Monday", "Tuesday", "Wednesday", 
                                                         "Thursday", "Friday", "Saturday", "Sunday")))  # Day of the week as ordered factor

Time Series Objects

Convert sales to time series objects for the use in several models

# convert to time series
sales_d_ts <- ts(df_merged_d$sales_cop)
sales_w_ts <- ts(df_merged_w$sales_w)
sales_m_ts <- ts(df_merged_m$sales_m)

par(mfrow=c(1,1))

# Daily
tsdisplay(sales_d_ts)

# is not stationary but has no clear trend
# and seasonality every 7 days

# Weekly
tsdisplay(sales_w_ts)

# not stationary: has trend

# Montly
tsdisplay(sales_m_ts)

# has clear trend, no seasonality

Log Transformation

Some variables are scaled to log, so we can interpret the linear models more easily. The covariates are in different scales so it is easier to interpret percentage changes instead of unit changes.

# Monthly
df_merged_m <- df_merged_m %>%
  mutate(across(where(is.numeric) & !all_of(c("unemployment", "inflation")), ~ log(. + 1)))

# Weekly
df_merged_w <- df_merged_w %>%
  mutate(across(where(is.numeric), ~ log(. + 1)))

# Daily
# Weekly
df_merged_d <- df_merged_d %>%
  mutate(across(where(is.numeric), ~ log(. + 1)))

Autocorrelation

#par(mfrow=c(1,1))
#tsdisplay(sales_d_ts)
# is not stationary but has no clear trend

plot(sales_d_ts)

acf(sales_d_ts)

pacf(sales_d_ts)

When data are seasonal, the autocorrelation will be larger for the seasonal lags (at multiples of the seasonal period) than for other lags.

# Weekly

#tsdisplay(sales_w_ts)
plot(sales_w_ts)

acf(sales_w_ts)

pacf(sales_w_ts)


# not stationary: has trend and seasonality maybe
# Montly

#tsdisplay(sales_m_ts)
plot(sales_m_ts)

acf(sales_m_ts)

pacf(sales_m_ts)

# has clear trend, no seasonality

Models

In this section we model the time series using various approaches to find the best model for our data. We use both linear and non linear models going from the simplest to the more “complex” models.

Helper functions

Functions that help us implement and analyze models faster

## Function to create and summarize models------------------
run_model <- function(formula, data, model_name) {
  cat("\nRunning", model_name, "\n")
  model <- lm(formula, data = data)
  print(summary(model))
  par(mfrow = c(2, 2))
  plot(model)
  return(model)
}

# Function to compare models using ANOVA
compare_models <- function(model1, model2, name1, name2) {
  cat("\nComparing Models:", name1, "vs", name2, "\n")
  anova_result <- anova(model1, model2)
  print(anova_result)
  return(anova_result)
}

# Function to add predictions to the dataset
add_predictions <- function(model, data, pred_column) {
  data[[pred_column]] <- predict(model, newdata = data)
  return(data)
}

# Calculate RMSE
# Function to calculate RMSE
calculate_rmse <- function(observed, predicted) {
  rmse <- sqrt(mean((observed - predicted)^2, na.rm = TRUE))
  return(rmse)
}


# function that compares linear models
# Define the function to get R^2 and AIC
get_model_stats <- function(models) {
  # Initialize an empty data frame
  stats <- data.frame(
    Model = character(),
    R2 = numeric(),
    AIC = numeric(),
    stringsAsFactors = FALSE
  )
  
  # Loop through the list of models
  for (i in seq_along(models)) {
    model <- models[[i]]
    model_name <- names(models)[i]
    # Extract R^2 and AIC
    r2 <- summary(model)$r.squared
    aic <- AIC(model)
    # Append to the data frame
    stats <- rbind(stats, data.frame(Model = model_name, R2 = r2, AIC = aic))
  }
  
  return(stats)
}

Linear models

# Montly Models
# View Dataframe
head(df_merged_m)

# Model 0: Trend only
ols0 <- run_model(sales_m ~ numeric_month, df_merged_m, "Model 0")

Running Model 0 

Call:
lm(formula = formula, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.9910 -0.1192  0.0158  0.1476  0.4953 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   16.40311    0.18031   90.97  < 2e-16 ***
numeric_month  0.68309    0.06312   10.82 1.49e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.28 on 34 degrees of freedom
Multiple R-squared:  0.775, Adjusted R-squared:  0.7684 
F-statistic: 117.1 on 1 and 34 DF,  p-value: 1.485e-12

df_merged_m <- add_predictions(ols0, df_merged_m, "predicted_sales0")

# Model 1: Trend + Seasonality
ols1 <- run_model(sales_m ~ numeric_month + seasonal_month, df_merged_m, "Model 1")

Running Model 1 

Call:
lm(formula = formula, data = data)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.7403 -0.1590 -0.0135  0.2071  0.4347 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)
(Intercept)             16.505470   0.260998  63.240  < 2e-16
numeric_month            0.657412   0.075865   8.666 1.06e-08
seasonal_monthFebruary  -0.001699   0.254032  -0.007    0.995
seasonal_monthMarch     -0.006230   0.254345  -0.024    0.981
seasonal_monthApril     -0.063031   0.254777  -0.247    0.807
seasonal_monthMay        0.070611   0.255288   0.277    0.785
seasonal_monthJune       0.037438   0.255855   0.146    0.885
seasonal_monthJuly       0.138742   0.256462   0.541    0.594
seasonal_monthAugust    -0.010812   0.257098  -0.042    0.967
seasonal_monthSeptember -0.133330   0.257755  -0.517    0.610
seasonal_monthOctober   -0.058397   0.258427  -0.226    0.823
seasonal_monthNovember  -0.335279   0.254924  -1.315    0.201
seasonal_monthDecember  -0.016084   0.254094  -0.063    0.950
                           
(Intercept)             ***
numeric_month           ***
seasonal_monthFebruary     
seasonal_monthMarch        
seasonal_monthApril        
seasonal_monthMay          
seasonal_monthJune         
seasonal_monthJuly         
seasonal_monthAugust       
seasonal_monthSeptember    
seasonal_monthOctober      
seasonal_monthNovember     
seasonal_monthDecember     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.311 on 23 degrees of freedom
Multiple R-squared:  0.8123,    Adjusted R-squared:  0.7144 
F-statistic: 8.296 on 12 and 23 DF,  p-value: 8.937e-06

df_merged_m <- add_predictions(ols1, df_merged_m, "predicted_sales1")


## Model 2: Backward Stepwise Regression 

# Start with the full model (excluding food and bar)
ols2_full <- lm(
  sales_m ~ numeric_month + seasonal_month + unemployment + ise + fx_m +
    google_m + temp_m + rain_m, 
  data = df_merged_m
)


# Perform backward stepwise regression
ols2_stepwise <- step(
  ols2_full, 
  direction = "backward",
  trace = 1 # Prints the stepwise regression process
)
Start:  AIC=-105.33
sales_m ~ numeric_month + seasonal_month + unemployment + ise + 
    fx_m + google_m + temp_m + rain_m

                 Df Sum of Sq     RSS      AIC
- unemployment    1   0.00381 0.67561 -107.124
- temp_m          1   0.01925 0.69105 -106.310
<none>                        0.67180 -105.327
- rain_m          1   0.09618 0.76798 -102.510
- seasonal_month 11   0.79857 1.47037  -99.128
- ise             1   0.17973 0.85153  -98.793
- fx_m            1   0.44902 1.12082  -88.900
- google_m        1   0.66138 1.33318  -82.654
- numeric_month   1   2.42351 3.09530  -52.331

Step:  AIC=-107.12
sales_m ~ numeric_month + seasonal_month + ise + fx_m + google_m + 
    temp_m + rain_m

                 Df Sum of Sq    RSS      AIC
- temp_m          1   0.03858 0.7142 -107.125
<none>                        0.6756 -107.124
- rain_m          1   0.12563 0.8012 -102.984
- seasonal_month 11   0.80318 1.4788 -100.923
- ise             1   0.17592 0.8515 -100.793
- fx_m            1   0.46250 1.1381  -90.349
- google_m        1   0.65864 1.3343  -84.625
- numeric_month   1   3.11738 3.7930  -47.013

Step:  AIC=-107.12
sales_m ~ numeric_month + seasonal_month + ise + fx_m + google_m + 
    rain_m

                 Df Sum of Sq    RSS      AIC
<none>                        0.7142 -107.125
- rain_m          1    0.0940 0.8082 -104.673
- seasonal_month 11    0.7847 1.4989 -102.437
- ise             1    0.1606 0.8748 -101.823
- fx_m            1    0.4343 1.1485  -92.022
- google_m        1    0.6466 1.3608  -85.916
- numeric_month   1    4.1118 4.8260  -40.342
# Summary of the final stepwise model
summary(ols2_stepwise)

Call:
lm(formula = sales_m ~ numeric_month + seasonal_month + ise + 
    fx_m + google_m + rain_m, data = df_merged_m)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.31229 -0.08760 -0.01030  0.09029  0.31789 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)
(Intercept)             -52.31160   19.99397  -2.616 0.016981
numeric_month             0.93626    0.08952  10.459 2.54e-09
seasonal_monthFebruary    0.27615    0.19812   1.394 0.179459
seasonal_monthMarch      -0.33136    0.28825  -1.150 0.264583
seasonal_monthApril      -0.03032    0.20910  -0.145 0.886232
seasonal_monthMay        -0.12629    0.27633  -0.457 0.652850
seasonal_monthJune       -0.16788    0.27401  -0.613 0.547361
seasonal_monthJuly       -0.11655    0.30708  -0.380 0.708483
seasonal_monthAugust     -0.45680    0.33544  -1.362 0.189189
seasonal_monthSeptember  -0.40348    0.27930  -1.445 0.164861
seasonal_monthOctober    -0.21625    0.28064  -0.771 0.450439
seasonal_monthNovember   -0.67606    0.38426  -1.759 0.094603
seasonal_monthDecember   -1.52898    0.67026  -2.281 0.034247
ise                       7.20920    3.48786   2.067 0.052641
fx_m                      2.72323    0.80115   3.399 0.003010
google_m                  3.17853    0.76636   4.148 0.000547
rain_m                   -0.20297    0.12835  -1.581 0.130285
                           
(Intercept)             *  
numeric_month           ***
seasonal_monthFebruary     
seasonal_monthMarch        
seasonal_monthApril        
seasonal_monthMay          
seasonal_monthJune         
seasonal_monthJuly         
seasonal_monthAugust       
seasonal_monthSeptember    
seasonal_monthOctober      
seasonal_monthNovember  .  
seasonal_monthDecember  *  
ise                     .  
fx_m                    ** 
google_m                ***
rain_m                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1939 on 19 degrees of freedom
Multiple R-squared:  0.9397,    Adjusted R-squared:  0.889 
F-statistic: 18.52 on 16 and 19 DF,  p-value: 2.609e-08
# Add predictions from the final stepwise model
df_merged_m <- add_predictions(ols2_stepwise, df_merged_m, "predicted_sales2")

# Plot Actual vs Predicted Values
ggplot(df_merged_m, aes(x = month)) +
  geom_line(aes(y = exp(sales_m), color = "Actual Sales"), size = 1) +
  geom_line(aes(y = exp(predicted_sales0), color = "Model 0"), linetype = "dashed", size = 1) +
  geom_line(aes(y = exp(predicted_sales1), color = "Model 1"), linetype = "dotted", size = 1) +
  geom_line(aes(y = exp(predicted_sales2), color = "Model 2 Stepwise"), linetype = "dotdash", size = 1) +
  labs(title = "Actual vs Predicted Monthly Sales for All Models",
       x = "Month", y = "Sales", color = "Legend") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))



# Models to compare
models <- list(
  "Model trend" = ols0,
  "Model trend + season" = ols1,
  "Model all covariates step" = ols2_stepwise
)

# Get R^2 and AIC for each model
model_stats <- get_model_stats(models)

# View the results
print(model_stats)


#  RMSE calculation for the original (exponentiated) scale
rmse_stats <- data.frame(
  Model = character(),
  RMSE = numeric(),
  stringsAsFactors = FALSE
)

# Loop through each model
for (i in seq_along(models)) {
  model_name <- names(models)[i]
  predicted_column <- paste0("predicted_sales", i - 1)  # Adjust column name index
  
  # Calculate RMSE on the original scale
  rmse <- calculate_rmse(
    observed = exp(df_merged_m$sales_m),          # Exponentiate actual values
    predicted = exp(df_merged_m[[predicted_column]])  # Exponentiate predicted values
  )
  
  # Append results to the RMSE stats table
  rmse_stats <- rbind(rmse_stats, data.frame(Model = model_name, RMSE = rmse))
}

# View RMSE statistics
print(rmse_stats)
NA
rmse_ols_m <- rmse_stats$RMSE[3]
rmse_ols_m
[1] 13229295
# Weekly Models
head(df_merged_w)
## Clean Data - Drop rows 1-2 because sales are 0 / was not open yet
df_merged_w <- df_merged_w %>% slice(-1, -2)

## Model 0A: Trend only
ols0w <- run_model(sales_w ~ numeric_week, df_merged_w, "Model 0A")

Running Model 0A 

Call:
lm(formula = formula, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.79976 -0.15274  0.02907  0.15945  0.62620 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  14.78396    0.10486  140.99   <2e-16 ***
numeric_week  0.49907    0.02464   20.25   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.232 on 151 degrees of freedom
Multiple R-squared:  0.7309,    Adjusted R-squared:  0.7291 
F-statistic: 410.2 on 1 and 151 DF,  p-value: < 2.2e-16

df_merged_w <- add_predictions(ols0w, df_merged_w, "predicted_sales0")

## Model 1A: Trend + Seasonality
ols1w <- run_model(sales_w ~ numeric_week + seasonal_month, df_merged_w, "Model 1A")

Running Model 1A 

Call:
lm(formula = formula, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.67646 -0.14198  0.01153  0.15503  0.55098 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)    
(Intercept)             14.80670    0.11510 128.640   <2e-16 ***
numeric_week             0.49526    0.02589  19.132   <2e-16 ***
seasonal_monthFebruary   0.02570    0.09019   0.285    0.776    
seasonal_monthMarch     -0.06118    0.08865  -0.690    0.491    
seasonal_monthApril     -0.02874    0.08878  -0.324    0.747    
seasonal_monthMay        0.06556    0.08879   0.738    0.462    
seasonal_monthJune       0.05271    0.08948   0.589    0.557    
seasonal_monthJuly       0.11376    0.08777   1.296    0.197    
seasonal_monthAugust    -0.01542    0.09172  -0.168    0.867    
seasonal_monthSeptember -0.09398    0.09038  -1.040    0.300    
seasonal_monthOctober   -0.05580    0.08864  -0.629    0.530    
seasonal_monthNovember   0.07442    0.09812   0.758    0.449    
seasonal_monthDecember  -0.13767    0.08816  -1.562    0.121    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2289 on 140 degrees of freedom
Multiple R-squared:  0.7571,    Adjusted R-squared:  0.7362 
F-statistic: 36.36 on 12 and 140 DF,  p-value: < 2.2e-16

df_merged_w <- add_predictions(ols1w, df_merged_w, "predicted_sales1")


## Model 2A: Experimentation


# Start with the full model (excluding food and bar)
ols2_full_w <- lm(
  sales_w ~ numeric_week + seasonal_month + fx_w +
    google_w + temp_w + rain_w, 
  data = df_merged_w
)


# Perform backward stepwise regression
ols2_stepwise_w <- step(
  ols2_full_w, 
  direction = "backward",
  trace = 1 # Prints the stepwise regression process
)
Start:  AIC=-474.75
sales_w ~ numeric_week + seasonal_month + fx_w + google_w + temp_w + 
    rain_w

                 Df Sum of Sq     RSS     AIC
- google_w        1    0.0017  5.5046 -476.70
- temp_w          1    0.0288  5.5317 -475.95
<none>                         5.5028 -474.75
- rain_w          1    0.2315  5.7343 -470.45
- seasonal_month 11    1.2581  6.7609 -465.25
- fx_w            1    1.3796  6.8825 -442.52
- numeric_week    1   11.9715 17.4743 -299.96

Step:  AIC=-476.7
sales_w ~ numeric_week + seasonal_month + fx_w + temp_w + rain_w

                 Df Sum of Sq     RSS     AIC
- temp_w          1    0.0281  5.5327 -477.92
<none>                         5.5046 -476.70
- rain_w          1    0.2325  5.7370 -472.38
- seasonal_month 11    1.2566  6.7612 -467.24
- fx_w            1    1.4037  6.9082 -443.95
- numeric_week    1   15.3205 20.8251 -275.12

Step:  AIC=-477.92
sales_w ~ numeric_week + seasonal_month + fx_w + rain_w

                 Df Sum of Sq     RSS     AIC
<none>                         5.5327 -477.92
- rain_w          1    0.2056  5.7384 -474.34
- seasonal_month 11    1.2336  6.7663 -469.13
- fx_w            1    1.3879  6.9206 -445.68
- numeric_week    1   16.3743 21.9070 -269.38
# Summary of the final stepwise model
summary(ols2_stepwise_w)

Call:
lm(formula = sales_w ~ numeric_week + seasonal_month + fx_w + 
    rain_w, data = df_merged_w)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.6258 -0.1168  0.0029  0.1220  0.5414 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)
(Intercept)             -0.795973   2.529046  -0.315   0.7534
numeric_week             0.514279   0.025448  20.209  < 2e-16
seasonal_monthFebruary   0.009356   0.079421   0.118   0.9064
seasonal_monthMarch     -0.002569   0.078234  -0.033   0.9739
seasonal_monthApril      0.064014   0.081105   0.789   0.4313
seasonal_monthMay        0.165794   0.082132   2.019   0.0455
seasonal_monthJune       0.179993   0.085195   2.113   0.0364
seasonal_monthJuly       0.153995   0.077211   1.994   0.0481
seasonal_monthAugust     0.001588   0.080384   0.020   0.9843
seasonal_monthSeptember -0.108556   0.079833  -1.360   0.1761
seasonal_monthOctober   -0.092775   0.078684  -1.179   0.2404
seasonal_monthNovember   0.088688   0.091541   0.969   0.3343
seasonal_monthDecember  -0.099444   0.078197  -1.272   0.2056
fx_w                     1.976626   0.335948   5.884 2.89e-08
rain_w                  -0.115589   0.051037  -2.265   0.0251
                           
(Intercept)                
numeric_week            ***
seasonal_monthFebruary     
seasonal_monthMarch        
seasonal_monthApril        
seasonal_monthMay       *  
seasonal_monthJune      *  
seasonal_monthJuly      *  
seasonal_monthAugust       
seasonal_monthSeptember    
seasonal_monthOctober      
seasonal_monthNovember     
seasonal_monthDecember     
fx_w                    ***
rain_w                  *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2002 on 138 degrees of freedom
Multiple R-squared:  0.8167,    Adjusted R-squared:  0.7982 
F-statistic: 43.93 on 14 and 138 DF,  p-value: < 2.2e-16
# Add predictions from the final stepwise model
df_merged_w <- add_predictions(ols2_stepwise_w, df_merged_w, "predicted_sales2")

# Plot Actual vs Predicted Values
ggplot(df_merged_w, aes(x = week)) +
  geom_line(aes(y = exp(sales_w), color = "Actual Sales"), size = 1) +
  geom_line(aes(y = exp(predicted_sales0), color = "Model 0"), linetype = "dashed", size = 1) +
  geom_line(aes(y = exp(predicted_sales1), color = "Model 1"), linetype = "dotted", size = 1) +
  geom_line(aes(y = exp(predicted_sales2), color = "Model 2 Stepwise"), linetype = "dotdash", size = 1) +
  labs(title = "Actual vs Predicted Weekly Sales for All Models",
       x = "Week", y = "Sales", color = "Legend") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))


# Models to compare
models_w <- list(
  "Model trend" = ols0w,
  "Model trend + season" = ols1w,
  "Model all covariates step" = ols2_stepwise_w
)

# Get R^2 and AIC for each model
model_stats_w <- get_model_stats(models_w)

# View the results
print(model_stats_w)


rmse_stats_w <- data.frame(
  Model = character(),
  RMSE = numeric(),
  stringsAsFactors = FALSE
)

# Loop through each model
for (i in seq_along(models_w)) {
  model_name <- names(models_w)[i]
  predicted_column <- paste0("predicted_sales", i - 1)  # Adjust column name index
  
  # Calculate RMSE on the original scale
  rmse <- calculate_rmse(
    observed = exp(df_merged_w$sales_w),          # Exponentiate actual values
    predicted = exp(df_merged_w[[predicted_column]])  # Exponentiate predicted values
  )
  
  # Append results to the RMSE stats table
  rmse_stats_w <- rbind(rmse_stats_w, data.frame(Model = model_name, RMSE = rmse))
}

# View RMSE statistics
print(rmse_stats_w)
NA
rmse_ols_w <- rmse_stats_w$RMSE[3]
rmse_ols_w
[1] 3909103
# Daily Models
head(df_merged_d,25)
# properly start in december
df_merged_d <-  df_merged_d %>%
  filter(date > "2021-11-30")
head(df_merged_d)

## Model 0: Trend only
ols0d <- run_model(sales_cop ~ numeric_day, df_merged_d, "Model 0A")

Running Model 0A 

Call:
lm(formula = formula, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2118  -0.1833   0.2033   0.5788   1.6889 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  10.4838     0.4287  24.456   <2e-16 ***
numeric_day   0.6831     0.0699   9.772   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.762 on 1037 degrees of freedom
Multiple R-squared:  0.08432,   Adjusted R-squared:  0.08344 
F-statistic:  95.5 on 1 and 1037 DF,  p-value: < 2.2e-16

df_merged_d <- add_predictions(ols0d, df_merged_d, "predicted_sales0")

## Model 1: Trend + Seasonality
ols1d <- run_model(sales_cop ~ numeric_day + seasonal_month + day_of_week, df_merged_d, "Model 1A")

Running Model 1A 

Call:
lm(formula = formula, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.1961  -0.1426   0.1547   0.4376   2.2118 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)    
(Intercept)             10.36800    0.46988  22.065  < 2e-16 ***
numeric_day              0.61107    0.07316   8.353  < 2e-16 ***
seasonal_monthFebruary   0.37605    0.26287   1.431  0.15286    
seasonal_monthMarch      0.24022    0.25678   0.936  0.34975    
seasonal_monthApril      0.21367    0.26029   0.821  0.41191    
seasonal_monthMay        0.03355    0.25766   0.130  0.89643    
seasonal_monthJune       0.15004    0.26178   0.573  0.56666    
seasonal_monthJuly       0.22890    0.25938   0.882  0.37773    
seasonal_monthAugust     0.24650    0.26028   0.947  0.34383    
seasonal_monthSeptember -0.04394    0.26445  -0.166  0.86806    
seasonal_monthOctober    0.22407    0.26395   0.849  0.39615    
seasonal_monthNovember   0.05368    0.29619   0.181  0.85622    
seasonal_monthDecember  -0.71696    0.25824  -2.776  0.00560 ** 
day_of_weekTuesday      -0.07884    0.19861  -0.397  0.69148    
day_of_weekWednesday     0.22688    0.19767   1.148  0.25133    
day_of_weekThursday      0.47554    0.19734   2.410  0.01614 *  
day_of_weekFriday        1.10956    0.19862   5.586 2.97e-08 ***
day_of_weekSaturday      0.93771    0.19827   4.730 2.57e-06 ***
day_of_weekSunday        0.61578    0.19825   3.106  0.00195 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.705 on 1020 degrees of freedom
Multiple R-squared:  0.1565,    Adjusted R-squared:  0.1417 
F-statistic: 10.52 on 18 and 1020 DF,  p-value: < 2.2e-16

df_merged_d <- add_predictions(ols1d, df_merged_d, "predicted_sales1")

# Model 2: Backward
head(df_merged_d)

# Start with the full model (excluding food and bar)
ols2_full_d <- lm(
  sales_cop ~ numeric_day + seasonal_month + day_of_week + fx +
     tmedian + rain_sum, 
  data = df_merged_d
)
summary(ols2_full_d)

Call:
lm(formula = sales_cop ~ numeric_day + seasonal_month + day_of_week + 
    fx + tmedian + rain_sum, data = df_merged_d)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2636  -0.1276   0.1461   0.4151   2.2576 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)
(Intercept)              3.279201   7.571387   0.433  0.66503
numeric_day              0.565330   0.079450   7.116 2.10e-12
seasonal_monthFebruary   0.406952   0.263751   1.543  0.12316
seasonal_monthMarch      0.252562   0.257085   0.982  0.32613
seasonal_monthApril      0.213593   0.264546   0.807  0.41963
seasonal_monthMay       -0.001365   0.263002  -0.005  0.99586
seasonal_monthJune       0.122006   0.268559   0.454  0.64971
seasonal_monthJuly       0.224695   0.260074   0.864  0.38781
seasonal_monthAugust     0.277725   0.260743   1.065  0.28707
seasonal_monthSeptember -0.003025   0.265704  -0.011  0.99092
seasonal_monthOctober    0.143398   0.266198   0.539  0.59022
seasonal_monthNovember  -0.132339   0.305424  -0.433  0.66489
seasonal_monthDecember  -0.742806   0.258943  -2.869  0.00421
day_of_weekTuesday      -0.075196   0.198313  -0.379  0.70464
day_of_weekWednesday     0.238097   0.197517   1.205  0.22831
day_of_weekThursday      0.472214   0.197048   2.396  0.01673
day_of_weekFriday        1.102508   0.198311   5.559 3.46e-08
day_of_weekSaturday      0.930469   0.197993   4.699 2.97e-06
day_of_weekSunday        0.615183   0.198117   3.105  0.00195
fx                       0.827866   0.881531   0.939  0.34789
tmedian                 -0.135956   0.999284  -0.136  0.89181
rain_sum                 0.136200   0.101044   1.348  0.17798
                           
(Intercept)                
numeric_day             ***
seasonal_monthFebruary     
seasonal_monthMarch        
seasonal_monthApril        
seasonal_monthMay          
seasonal_monthJune         
seasonal_monthJuly         
seasonal_monthAugust       
seasonal_monthSeptember    
seasonal_monthOctober      
seasonal_monthNovember     
seasonal_monthDecember  ** 
day_of_weekTuesday         
day_of_weekWednesday       
day_of_weekThursday     *  
day_of_weekFriday       ***
day_of_weekSaturday     ***
day_of_weekSunday       ** 
fx                         
tmedian                    
rain_sum                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.702 on 1017 degrees of freedom
Multiple R-squared:  0.1618,    Adjusted R-squared:  0.1445 
F-statistic: 9.349 on 21 and 1017 DF,  p-value: < 2.2e-16
# Perform backward stepwise regression
ols2_stepwise_d <- step(
  ols2_full_d, 
  direction = "backward",
  trace = 1 # Prints the stepwise regression process
)
Start:  AIC=1127.38
sales_cop ~ numeric_day + seasonal_month + day_of_week + fx + 
    tmedian + rain_sum

                 Df Sum of Sq    RSS    AIC
- tmedian         1     0.054 2947.6 1125.4
- fx              1     2.556 2950.1 1126.3
- rain_sum        1     5.266 2952.8 1127.2
<none>                        2947.6 1127.4
- seasonal_month 11    79.060 3026.6 1132.9
- numeric_day     1   146.743 3094.3 1175.9
- day_of_week     6   177.279 3124.8 1176.1

Step:  AIC=1125.4
sales_cop ~ numeric_day + seasonal_month + day_of_week + fx + 
    rain_sum

                 Df Sum of Sq    RSS    AIC
- fx              1     2.515 2950.1 1124.3
<none>                        2947.6 1125.4
- rain_sum        1     5.915 2953.5 1125.5
- seasonal_month 11    79.341 3026.9 1131.0
- day_of_week     6   177.262 3124.9 1174.1
- numeric_day     1   149.907 3097.5 1174.9

Step:  AIC=1124.29
sales_cop ~ numeric_day + seasonal_month + day_of_week + rain_sum

                 Df Sum of Sq    RSS    AIC
<none>                        2950.1 1124.3
- rain_sum        1    15.917 2966.0 1127.9
- seasonal_month 11    78.865 3029.0 1129.7
- day_of_week     6   176.760 3126.9 1172.7
- numeric_day     1   147.563 3097.7 1173.0
# Summary of the final stepwise model
summary(ols2_stepwise_d)

Call:
lm(formula = sales_cop ~ numeric_day + seasonal_month + day_of_week + 
    rain_sum, data = df_merged_d)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.1848  -0.1398   0.1461   0.4324   2.3762 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)    
(Intercept)              9.49003    0.60001  15.816  < 2e-16 ***
numeric_day              0.55165    0.07727   7.139 1.78e-12 ***
seasonal_monthFebruary   0.42084    0.26299   1.600  0.10986    
seasonal_monthMarch      0.23726    0.25622   0.926  0.35466    
seasonal_monthApril      0.17038    0.26037   0.654  0.51301    
seasonal_monthMay       -0.03721    0.25886  -0.144  0.88573    
seasonal_monthJune       0.07280    0.26327   0.277  0.78220    
seasonal_monthJuly       0.20776    0.25897   0.802  0.42259    
seasonal_monthAugust     0.27190    0.25993   1.046  0.29579    
seasonal_monthSeptember  0.01008    0.26487   0.038  0.96964    
seasonal_monthOctober    0.16643    0.26452   0.629  0.52938    
seasonal_monthNovember  -0.12439    0.30514  -0.408  0.68362    
seasonal_monthDecember  -0.74920    0.25804  -2.903  0.00377 ** 
day_of_weekTuesday      -0.07454    0.19818  -0.376  0.70690    
day_of_weekWednesday     0.24211    0.19734   1.227  0.22017    
day_of_weekThursday      0.47096    0.19691   2.392  0.01695 *  
day_of_weekFriday        1.10237    0.19820   5.562 3.41e-08 ***
day_of_weekSaturday      0.92890    0.19787   4.695 3.04e-06 ***
day_of_weekSunday        0.61671    0.19782   3.118  0.00187 ** 
rain_sum                 0.19036    0.08119   2.345  0.01923 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.702 on 1019 degrees of freedom
Multiple R-squared:  0.1611,    Adjusted R-squared:  0.1454 
F-statistic:  10.3 on 19 and 1019 DF,  p-value: < 2.2e-16
# Add predictions from the final stepwise model
df_merged_d <- add_predictions(ols2_stepwise_d, df_merged_d, "predicted_sales2")

# Plot Actual vs Predicted Values
ggplot(df_merged_d, aes(x = date)) +
  geom_line(aes(y = exp(sales_cop), color = "Actual Sales"), size = 1) +
  geom_line(aes(y = exp(predicted_sales0), color = "Model 0"), linetype = "dashed", size = 1) +
  geom_line(aes(y = exp(predicted_sales1), color = "Model 1"), linetype = "dotted", size = 1) +
  geom_line(aes(y = exp(predicted_sales2), color = "Model 2 Stepwise"), linetype = "dotdash", size = 1) +
  labs(title = "Actual vs Predicted Sales for All Models",
       x = "date", y = "Sales", color = "Legend") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))



# Models to compare
models_d <- list(
  "Model trend" = ols0d,
  "Model trend + season" = ols1d,
  "Model all covariates step" = ols2_stepwise_d
)

# Get R^2 and AIC for each model
model_stats_d <- get_model_stats(models_d)

# View the results
print(model_stats_d)

#  RMSE calculation for the original (exponentiated) scale for daily models
rmse_stats_d <- data.frame(
  Model = character(),
  RMSE = numeric(),
  stringsAsFactors = FALSE
)

# Loop through each model
for (i in seq_along(models_d)) {
  model_name <- names(models_d)[i]
  predicted_column <- paste0("predicted_sales", i - 1)  # Adjust column name index
  
  # Calculate RMSE on the original scale
  rmse <- calculate_rmse(
    observed = exp(df_merged_d$sales_cop),          # Exponentiate actual values
    predicted = exp(df_merged_d[[predicted_column]])  # Exponentiate predicted values
  )
  
  # Append results to the RMSE stats table
  rmse_stats_d <- rbind(rmse_stats_d, data.frame(Model = model_name, RMSE = rmse))
}

# View RMSE statistics for daily data
print(rmse_stats_d)
rmse_ols_d <- rmse_stats_d$RMSE[3]
rmse_ols_d
[1] 1425907

Non Linear Models

Here we explore non linear models, starting from the simplest to more elaborate models in the end combining some of the used models.

Wrangle data for models

The time series are altered so the visualizations are more understandable, basically we change the date index in the timeseries objects

# re-declare time-series beacause we droped some rows:
# Ensure the 'date' columns are in Date format
df_merged_d$date <- as.Date(df_merged_d$date)
df_merged_w$date <- as.Date(df_merged_w$week)
df_merged_m$date <- as.Date(df_merged_m$month)

# Extract the start date and year for each dataframe
start_d <- min(df_merged_d$date)
start_w <- min(df_merged_w$date)
start_m <- min(df_merged_m$date)

# Extract components for daily, weekly, and monthly start times
start_d_year <- as.numeric(format(start_d, "%Y"))
start_d_day <- as.numeric(format(start_d, "%j")) # Day of the year

start_w_year <- as.numeric(format(start_w, "%Y"))
start_w_week <- as.numeric(format(start_w, "%U")) + 1 # Week number, adding 1 since R starts at week 0

start_m_year <- as.numeric(format(start_m, "%Y"))
start_m_month <- as.numeric(format(start_m, "%m"))

# Declare time series with appropriate frequencies
sales_d_ts <- ts(exp(df_merged_d$sales_cop), start = c(start_d_year, start_d_day), frequency = 365)
sales_w_ts <- ts(exp(df_merged_w$sales_w), start = c(start_w_year, start_w_week), frequency = 52)
sales_m_ts <- ts(exp(df_merged_m$sales_m), start = c(start_m_year, start_m_month), frequency = 12)

food_d_ts <- ts(exp(df_merged_d$food), start = c(start_d_year, start_d_day), frequency = 365)
food_w_ts <- ts(exp(df_merged_w$food_w), start = c(start_w_year, start_w_week), frequency = 52)
food_m_ts <- ts(exp(df_merged_m$food_m), start = c(start_m_year, start_m_month), frequency = 12)

bar_d_ts <- ts(exp(df_merged_d$bar), start = c(start_d_year, start_d_day), frequency = 365)
bar_w_ts <- ts(exp(df_merged_w$bar_w), start = c(start_w_year, start_w_week), frequency = 52)
bar_m_ts <- ts(exp(df_merged_m$bar_m), start = c(start_m_year, start_m_month), frequency = 12)
# Verify the created time series
par(mfrow=c(1,1))
plot(sales_d_ts)

plot(sales_w_ts)

plot(sales_m_ts)



plot(food_d_ts)

plot(food_w_ts)

plot(food_m_ts)


plot(bar_d_ts)

plot(bar_w_ts)

plot(bar_m_ts)

Here we fill the sales = 0 values with the mean of the two adjacent dates. This in order to have smoother models. The dates with sales = 0 are dates that are national holiday like christmas or new years, or inventory day in which the kitchen cannot operate so the sales are 0.

# Function to replace 1s with the mean of previous and next observations
fill_ones <- function(ts_data) {
  # Convert time series to numeric vector
  ts_vec <- as.numeric(ts_data)
  
  # Loop through and replace 1s
  for (i in seq_along(ts_vec)) {
    if (ts_vec[i] == 1) {
      # Check boundaries to avoid indexing issues
      prev_val <- ifelse(i > 1, ts_vec[i - 1], NA)
      next_val <- ifelse(i < length(ts_vec), ts_vec[i + 1], NA)
      
      # Replace with mean of previous and next, ignoring NA
      ts_vec[i] <- mean(c(prev_val, next_val), na.rm = TRUE)
    }
  }
  
  # Return as time series with original attributes
  ts(ts_vec, start = start(ts_data), frequency = frequency(ts_data))
}

# Apply the function 
sales_d_ts <- fill_ones(sales_d_ts)
sales_w_ts <- fill_ones(sales_w_ts)
sales_m_ts <- fill_ones(sales_m_ts)


food_d_ts <- fill_ones(food_d_ts)
food_w_ts <- fill_ones(food_w_ts)
food_m_ts <- fill_ones(food_m_ts)

bar_d_ts <- fill_ones(bar_d_ts)
bar_w_ts <- fill_ones(bar_w_ts)
bar_m_ts <- fill_ones(bar_m_ts)

Bass Model

# Some simple plots
plot(sales_m_ts)

plot(cumsum(sales_m_ts)) #Returns a vector whose elements are the cumulative sums

# Bass model
bm_m<-BM(sales_m_ts,display = T) # show graphical view of results / display = True


summary(bm_m)
Call: ( Standard Bass Model )

  BM(series = sales_m_ts, display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-94382506 -37311459 -12636337 -10394220  24066002  75506534 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  47282474  on  33  degrees of freedom
 Multiple R-squared:   0.999374  Residual sum of squares:  7.377587e+16
bm_m$coefficients['m'] - sum(sales_m_ts)
         m 
1148560231 

According to this, there are only 1m cop left to sell, this is less than a year / seems wrong. Fits well but the 30- onward is wierd + sales might not be declining yet. Still reflects the innovation and copying in some sense

Also the restaurants rely in word of mouth to reach full stage m = 4.664.000.000 COP, i.e 1 mm EUR approx. / The restaurant has sold 3.515.788.885/ According to this only in 1 year it should extinguish sells p, innovation: 0.832% indicates that the adoption rate due to external influence is relatively low, but not uncommon for many markets. - it is actually relativly innovative q: (8.96%) suggests that imitation plays a larger role than innovation in driving adoption in this market

pred_bm_m<- predict(bm_m, newx=c(1:length(sales_m_ts)))
pred_bm_m <- ts(pred_bm_m, start = start(sales_m_ts), frequency = frequency(sales_m_ts))
pred.inst_bm_m <- make.instantaneous(pred_bm_m)
pred.inst_bm_m <- ts(pred.inst_bm_m, start = start(sales_m_ts), frequency = frequency(sales_m_ts))

# plot
plot(sales_m_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Month", ylab = "Monthly Sales", main = "Actual vs Fitted Sales")

# Add the fitted values as a line
lines(pred.inst_bm_m, col = "red", lwd = 2)

# Add a legend
legend("topleft", legend = c("Actual Values", "Fitted Values"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))

# check residuals
res_bm_m <- sales_m_ts - pred.inst_bm_m
tsdisplay(res_bm_m)

Residuals have some structure and 2 lag has correlation.

# Calculate RMSE for Bass Model predictions
rmse_bm_m <- calculate_rmse(observed = sales_m_ts, predicted = pred.inst_bm_m)

# Print the RMSE
cat("RMSE for Bass Model Predictions:", rmse_bm_m, "\n")
RMSE for Bass Model Predictions: 18498870 
bm_w<-BM(sales_w_ts,display = T) # show graphical view of results / display = True
summary(bm_w)
bm_w$coefficients['m'] - sum(sales_w_ts)
# results are similar in terms of m, p and w are in other scale 
#because they are in different time stamp
bm_m$coefficients['q'] / bm_w$coefficients['q'] # they are approx 4 times
bm_m$coefficients['p'] / bm_w$coefficients['p'] # they are approx 4 times
# which makes sense

Coefficients are approximatly 4 times the ones of the monthly model, making sense because there are 4 weeks in a month. While market potential is similar.

# Prediction
pred_bm_w<- predict(bm_w, newx=c(1:length(sales_w_ts)))
pred_bm_w <- ts(pred_bm_w, start = start(sales_w_ts), frequency = frequency(sales_w_ts))
pred.inst_bm_w <- make.instantaneous(pred_bm_w)
pred.inst_bm_w <- ts(pred.inst_bm_w, start = start(sales_w_ts), frequency = frequency(sales_w_ts))

# plot
plot(sales_w_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Week", ylab = "Weekly Sales", main = "Actual vs Fitted Sales")

# Add the fitted values as a line
lines(pred.inst_bm_w, col = "red", lwd = 2)

# Add a legend
legend("topleft", legend = c("Actual Values", "Fitted Values"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))
# check residuals
res_bm_w <- sales_w_ts - pred.inst_bm_w
tsdisplay(res_bm_w)

Residuals have some structure and 2 lag has correlation, with clear trend and structure in the residuals

# RMSE
# Calculate RMSE for Bass Model predictions
rmse_bm_w <- calculate_rmse(observed = sales_w_ts, predicted = pred.inst_bm_w)

# Print the RMSE
cat("RMSE for Bass Model Predictions:", rmse_bm_w, "\n")
bm_d <- BM(
  sales_d_ts,
  prelimestimates = c(1.2 * sum(sales_d_ts), 0.005, 0.5), # Adjust these estimates
  display = TRUE
)


summary(bm_d)
bm_d$coefficients['m'] - sum(sales_d_ts)
# results are similar in terms of m, p and w are in other scale 
#because they are in different time stamp
bm_w$coefficients['q'] / bm_d$coefficients['q'] # they are approx 7 times
bm_w$coefficients['p'] / bm_d$coefficients['p'] # they are approx 7 times

Coefficients are approximately 1:7 scale of the ones in the weekly model, making sense. The market potential is also similar in order of magnitude.

# Prediction
pred_bm_d <- predict(bm_d, newx = c(1:length(sales_d_ts)))
pred_bm_d <- ts(pred_bm_d, start = start(sales_d_ts), frequency = frequency(sales_d_ts))
pred.inst_bm_d <- make.instantaneous(pred_bm_d)
pred.inst_bm_d <- ts(pred.inst_bm_d, start = start(sales_d_ts), frequency = frequency(sales_d_ts))

# Plot actual vs fitted sales for daily data
plot(sales_d_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Day", ylab = "Daily Sales", main = "Actual vs Fitted Sales (Daily)")

# Add the fitted values as a line
lines(pred.inst_bm_d, col = "red", lwd = 2)

# Add a legend
legend("topleft", legend = c("Actual Values", "Fitted Values"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))
# Check residuals
res_bm_d <- sales_d_ts - pred.inst_bm_d
tsdisplay(res_bm_d)

Residuals don not seem stationary, or at least they have a lot of autocorrelation.

# Calculate RMSE for Bass Model predictions (daily data)
rmse_bm_d <- calculate_rmse(observed = sales_d_ts, predicted = pred.inst_bm_d)

# Print the RMSE
cat("RMSE for Daily Bass Model Predictions:", rmse_bm_d, "\n")

Limitation of of the Bass Model

  • Bass model assumes that every product succeeds and the sales saturate to the steady state level. However, most new products fail in reality.

  • The market potential m is constant along the whole life cycle.

  • Bass model predictions works well only after the scale inflection point. if sales of a category goes up and up like a J-curve, it can over estimate the overall market size.

  • It is a model for products with a limited life cycle: needs a hypothesis.

  • Another drawback of Bass model is that the diffusion pattern in not affected by marketing mix variables like price or advertising.

The generalized Bass model extends the original Bass model allowing the roles of marketing mix value.

Generalized Bass Model

Bass model is used to forecast the adoption of a new product and to predict the sales, since it determines the shape of the curve of a model that represent the cumulative adoption of a new product. The Generalized Bass model extends the original Bass model by incorporating marketing mix variables. We can know the effect of pricing, promotions on the new product diffusion curve. It is more flexible than the original Bass model.


m <- 4.451570e+09
p <- 8.472917e-03
q <- 9.415625e-02

GBM_monthly_sales <- GBM(
  sales_m_ts, 
  shock = 'exp', 
  nshock = 1,
  #prelimestimates = c(m,p,q, 12, 0.1, -0.1)
  prelimestimates = c(m,p,q, 10, 0.1, 2)
  #prelimestimates = c(m,p,q, 11, 15, -0.1)
  )

summary(GBM_monthly_sales)

pred_GBM_monthly_sales<- predict(GBM_monthly_sales, newx=c(1:60))
pred_GBM_monthly_sales.inst<- make.instantaneous(pred_GBM_monthly_sales)

Guseo-Guidolin Model

# Montly model
ggm1 <- GGM(sales_m_ts, mt='base', display = T)
Warning: NaNs producedWarning: NaNs producedWarning: NaNs producedWarning: NaNs producedWarning: NaNs producedWarning: NaNs produced

ggm2 <- GGM(sales_m_ts, mt= function(x) pchisq(x,10),display = T)

summary(ggm1)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_m_ts, mt = "base", display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-27544719  -8809035    742251   -337148   7701034  23238738 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  13318300  on  31  degrees of freedom
 Multiple R-squared:   0.999873  Residual sum of squares:  5.498691e+15
summary(ggm2)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_m_ts, mt = function(x) pchisq(x, 10), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-55479254 -21799576   5818484  25726804  63528263 144216338 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  64933559  on  33  degrees of freedom
 Multiple R-squared:   0.99678  Residual sum of squares:  1.391401e+17
# try different functions for market potential

ggm3 <- GGM(sales_m_ts, mt= function(x) log(x),display = T)

ggm4 <- GGM(sales_m_ts, mt= function(x) (x)**(1/1.05),display = T)

summary(ggm3)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_m_ts, mt = function(x) log(x), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-51543377 -17143219  -1444208  -3434599   7197387  38682408 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  23487767  on  33  degrees of freedom
 Multiple R-squared:   0.999579  Residual sum of squares:  1.820528e+16
summary(ggm4)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_m_ts, mt = function(x) (x)^(1/1.05), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-33877044  -9900757   -986705  -1517515  10675797  29488516 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  16905824  on  33  degrees of freedom
 Multiple R-squared:   0.999782  Residual sum of squares:  9.431627e+15

K <- 7.683785e+09

pc <- 2.698613e-02

qc <- 2.582412e-01

ps <- 7.731763e-03

qs <- 4.508202e-02

# predictions
pred_ggm_m <- predict(ggm1, newx = c(1:length(sales_m_ts)))
pred_ggm_m <- ts(pred_ggm_m, start = start(sales_m_ts), frequency = frequency(sales_m_ts))
pred.inst_ggm_m <- make.instantaneous(pred_ggm_m)
pred.inst_ggm_m <- ts(pred.inst_ggm_m, start = start(sales_m_ts), frequency = frequency(sales_m_ts))

# Plot actual vs fitted sales for monthly data
plot(sales_m_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Month", ylab = "Monthly Sales", main = "Actual vs Fitted Sales (GGM Model)")

# Add the fitted values as a line
lines(pred.inst_ggm_m, col = "red", lwd = 2)

# Add a legend
legend("topleft", legend = c("Actual Values", "Fitted Values (GGM)"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))

#Analysis of residuals
res_GGM_m<- sales_m_ts - pred.inst_ggm_m
tsdisplay(res_GGM_m)

Residuals look stationary for this model

# Residuals somehow are kind of stationary
# check for stationarity of residuals
adf_test <- adf.test(res_GGM_m)
print(adf_test) # if p-val < alpha, series stationary

    Augmented Dickey-Fuller Test

data:  res_GGM_m
Dickey-Fuller = -4.1, Lag order = 3, p-value = 0.01708
alternative hypothesis: stationary
# so with this model we achieve stationary series

# check for autocorrelation in residuals
Box.test(res_GGM_m, lag = 10, type = "Ljung-Box") # h0 res indep

    Box-Ljung test

data:  res_GGM_m
X-squared = 16.263, df = 10, p-value = 0.09234
# p-val > alpha => fail to reject h0, so residuals seem indep

Residuals are likeley stationary

# Calculate RMSE for ggm1
rmse_ggm1 <- calculate_rmse(observed = sales_m_ts, predicted = pred.inst_ggm_m)

# Print RMSE for ggm1
cat("RMSE for GGM Model 1 (Base):", rmse_ggm1, "\n")
RMSE for GGM Model 1 (Base): 11759505 
# Weekly
ggm1_w <- GGM(sales_w_ts, mt='base', display = T)

ggm2_w <- GGM(sales_w_ts, mt= function(x) pchisq(x,25),display = T)

summary(ggm1_w) # this one is better
Call: ( Guseo Guidolin Model )

  GGM(series = sales_w_ts, mt = "base", display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-31498207  -8733958   2309014    276818   8889298  21142720 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  12329105  on  148  degrees of freedom
 Multiple R-squared:   0.999873  Residual sum of squares:  2.249701e+16
summary(ggm2_w)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_w_ts, mt = function(x) pchisq(x, 25), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-33750595 -17052328   2617278   9791490  29825798 107962582 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  36797065  on  150  degrees of freedom
 Multiple R-squared:   0.998856  Residual sum of squares:  2.031036e+17
# try different functions for market potential

ggm3_w <- GGM(sales_w_ts, mt= function(x) log(x),display = T)

ggm4_w <- GGM(sales_w_ts, mt= function(x) (x)**(1/1.05),display = T)


summary(ggm3_w)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_w_ts, mt = function(x) log(x), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-56356239 -18752252  -3739136  -3874766   8381947  42340483 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  23371927  on  150  degrees of freedom
 Multiple R-squared:   0.999539  Residual sum of squares:  8.193705e+16
summary(ggm4_w) # better shaped but less significant
Call: ( Guseo Guidolin Model )

  GGM(series = sales_w_ts, mt = function(x) (x)^(1/1.05), display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-33312923  -9281560   1900857    133074  10271969  26473496 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  13629605  on  150  degrees of freedom
 Multiple R-squared:   0.999843  Residual sum of squares:  2.786492e+16
# predictions
pred_ggm_w <- predict(ggm1_w, newx = c(1:length(sales_w_ts)))
pred_ggm_w <- ts(pred_ggm_w, start = start(sales_w_ts), frequency = frequency(sales_w_ts))
pred.inst_ggm_w <- make.instantaneous(pred_ggm_w)
pred.inst_ggm_w <- ts(pred.inst_ggm_w, start = start(sales_w_ts), frequency = frequency(sales_w_ts))

# Plot actual vs fitted sales for weekly data
plot(sales_w_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Week", ylab = "Weekly Sales", main = "Actual vs Fitted Sales (GGM Model)")

# Add the fitted values as a line
lines(pred.inst_ggm_w, col = "red", lwd = 2)

# Add a legend
legend("topleft", legend = c("Actual Values", "Fitted Values (GGM)"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))

# Analysis of residuals
res_GGM_w <- sales_w_ts - pred.inst_ggm_w
tsdisplay(res_GGM_w)



# Check for stationarity of residuals
adf_test_w <- adf.test(res_GGM_w)
Warning: p-value smaller than printed p-value
print(adf_test_w) # if p-value < alpha, series is stationary

    Augmented Dickey-Fuller Test

data:  res_GGM_w
Dickey-Fuller = -4.277, Lag order = 5, p-value = 0.01
alternative hypothesis: stationary
# Check for autocorrelation in residuals
box_test_w <- Box.test(res_GGM_w, lag = 10, type = "Ljung-Box")
print(box_test_w) # if p-value > alpha, residuals are independent

    Box-Ljung test

data:  res_GGM_w
X-squared = 54.208, df = 10, p-value = 4.437e-08

Series is stationary according to tests, but clearly has strong autocorrelation

# RMSE
rmse_ggm_w <- calculate_rmse(observed = sales_w_ts, predicted = pred.inst_ggm_w)

# Print the RMSE
cat("RMSE for Weekly GGM Model Predictions:", rmse_ggm_w, "\n")
RMSE for Weekly GGM Model Predictions: 3488834 
# Daily GGM
# Scaling the sales data
sales_min <- min(sales_d_ts)
sales_max <- max(sales_d_ts)
sales_scaled <- (sales_d_ts - sales_min) / (sales_max - sales_min)

# View scaled data
summary(sales_scaled)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.1911  0.2868  0.3219  0.4343  1.0000 
plot(sales_scaled, type = "l", main = "Scaled Daily Sales", xlab = "Day", ylab = "Scaled Sales")

We re-scale the data because else the model won’t converge

# Fit GGM models using scaled data
ggm1_d <- GGM(sales_scaled, mt = 'base', display = T)
Warning: NaNs producedWarning: NaNs producedWarning: NaNs produced

ggm2_d <- GGM(sales_scaled, mt = function(x) pchisq(x, 10), display = T)

ggm3_d <- GGM(sales_scaled, mt = function(x) log(x), display = T)

ggm4_d <- GGM(sales_scaled, mt = function(x) (x)^(1/1.05), display = T)


# Summarize models
summary(ggm1_d)  # Base model
Call: ( Guseo Guidolin Model )

  GGM(series = sales_scaled, mt = "base", display = T)

Residuals:
     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-3.40209 -0.89405  0.18000  0.03836  0.97389  2.48042 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  1.199911  on  1034  degrees of freedom
 Multiple R-squared:   0.999863  Residual sum of squares:  1488.74
summary(ggm2_d)  # Chi-squared
Call: ( Guseo Guidolin Model )

  GGM(series = sales_scaled, mt = function(x) pchisq(x, 10), display = T)

Residuals:
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-7.8716 -2.8996 -0.9350 -0.6934  1.6547  7.6841 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  3.370771  on  1036  degrees of freedom
 Multiple R-squared:   0.998915  Residual sum of squares:  11771.13
summary(ggm3_d)  # Log transformation
Call: ( Guseo Guidolin Model )

  GGM(series = sales_scaled, mt = function(x) log(x), display = T)

Residuals:
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-6.0610 -2.1289 -0.4068 -0.4506  1.0511  5.8698 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  2.488528  on  1036  degrees of freedom
 Multiple R-squared:   0.999409  Residual sum of squares:  6415.712
summary(ggm4_d)  # Power transformation
Call: ( Guseo Guidolin Model )

  GGM(series = sales_scaled, mt = function(x) (x)^(1/1.05), display = T)

Residuals:
     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-3.33604 -0.98757  0.18545  0.07343  0.93872  3.00560 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  1.301786  on  1036  degrees of freedom
 Multiple R-squared:   0.999838  Residual sum of squares:  1755.654

Predict on the best model based on fit and p-values We select model 1

# Prediction using GGM model
pred_ggm_d <- predict(ggm1_d, newx = c(1:length(sales_scaled)))
pred_ggm_d <- ts(pred_ggm_d, start = start(sales_scaled), frequency = frequency(sales_scaled))
pred.inst_ggm_d <- make.instantaneous(pred_ggm_d)
pred.inst_ggm_d <- ts(pred.inst_ggm_d, start = start(sales_scaled), frequency = frequency(sales_scaled))

# Re-scale predictions back to the original scale
pred_original_scale <- (pred.inst_ggm_d * (sales_max - sales_min)) + sales_min

# Plot actual vs fitted sales (original scale)
plot(sales_d_ts, type = "p", col = "black", pch = 16, cex = 0.7,
     xlab = "Day", ylab = "Daily Sales", main = "Actual vs Fitted Sales (Original Scale)")
lines(pred_original_scale, col = "red", lwd = 2)
legend("topleft", legend = c("Actual Values", "Fitted Values (GGM, Original Scale)"),
       col = c("black", "red"), pch = c(16, NA), lty = c(NA, 1), lwd = c(NA, 2))

# Analysis of residuals
res_GGM_d <- sales_d_ts - pred_original_scale
tsdisplay(res_GGM_d, main = "Residuals of GGM Model")

Residuals dont look stationary

# Check for stationarity of residuals
adf_test_d <- adf.test(res_GGM_d)
Warning: p-value smaller than printed p-value
print(adf_test_d)  # If p-value < alpha, series is stationary

    Augmented Dickey-Fuller Test

data:  res_GGM_d
Dickey-Fuller = -7.7728, Lag order = 10, p-value = 0.01
alternative hypothesis: stationary
# according to this, they are stationary

# Check for autocorrelation in residuals
box_test_d <- Box.test(res_GGM_d, lag = 10, type = "Ljung-Box")
print(box_test_d)  # If p-value > alpha, residuals are indep

    Box-Ljung test

data:  res_GGM_d
X-squared = 1405.1, df = 10, p-value < 2.2e-16

Residuals look stationary in the test but hey have serial correlation

# Calculate RMSE for GGM model predictions (original scale)
rmse_ggm_d <- calculate_rmse(observed = sales_d_ts, predicted = pred_original_scale)

# Print the RMSE
cat("RMSE for Daily GGM Model Predictions (Original Scale):", rmse_ggm_d, "\n")
RMSE for Daily GGM Model Predictions (Original Scale): 1600828 

Holt-Winters Model

# adjust timeseries to ensure date consistency
sales_m_ts <- ts(sales_m_ts, frequency=12, start=c(2021, 11))

hw1_m<- hw(sales_m_ts, seasonal="additive")
hw2_m<- hw(sales_m_ts, seasonal="multiplicative")

# prediction
fitted_hw1 <- hw1_m$fitted
fitted_hw2 <- hw2_m$fitted

We now plot the models

# Create a data frame for ggplot
plot_data <- data.frame(
  Time = time(sales_m_ts),
  Actual = as.numeric(sales_m_ts),
  Fitted_Additive = as.numeric(hw1_m$fitted),
  Fitted_Multiplicative = as.numeric(hw2_m$fitted)
)

# Melt data for easier ggplot usage
library(reshape2)
plot_data_melted <- melt(plot_data, id.vars = "Time", 
                         variable.name = "Series", 
                         value.name = "Value")

# Plot using ggplot2
ggplot(plot_data_melted, aes(x = Time, y = Value, color = Series)) +
  geom_point(data = subset(plot_data_melted, Series == "Actual"), size = 2) + # Actual values as dots
  geom_line(data = subset(plot_data_melted, Series != "Actual"), size = 1) +  # Fitted values as lines
  labs(
    title = "Actual vs Fitted Values",
    x = "Time",
    y = "Value",
    color = "Series"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Fitted_Additive" = "blue", "Fitted_Multiplicative" = "red"),
    labels = c("Actual", "Fitted (Additive)", "Fitted (Multiplicative)")
  ) +
  theme_minimal() +
  theme(
    legend.position = "top",
    legend.title = element_text(face = "bold")
  )

Looks like the multiplicative models follows the data more more closely in general.

# residuals
residuals_hw1 <- residuals(hw1_m)  
residuals_hw2 <- residuals(hw2_m)  
tsdisplay(residuals_hw1)

tsdisplay(residuals_hw2)

# Stationarity and Correlation
# check for stationarity of residuals
# additive
adf_test <- adf.test(residuals_hw1) # H0: series is non-stationary
print(adf_test) # if p-val < alpha, series not stationary

    Augmented Dickey-Fuller Test

data:  residuals_hw1
Dickey-Fuller = -1.8495, Lag order = 3, p-value = 0.6317
alternative hypothesis: stationary
# so with this model we achieve stationary series
# multiplicative
adf_test <- adf.test(residuals_hw2) # H0: series is non-stationary
print(adf_test) # if p-val < alpha, series not stationary

    Augmented Dickey-Fuller Test

data:  residuals_hw2
Dickey-Fuller = -2.0941, Lag order = 3, p-value = 0.5365
alternative hypothesis: stationary
# so with this model we achieve stationary series

# additive
# check for autocorrelation in residuals
Box.test(residuals_hw1, lag = 10, type = "Ljung-Box") # h0 res indep

    Box-Ljung test

data:  residuals_hw1
X-squared = 4.8498, df = 10, p-value = 0.901
# p-val > alpha =>  Dont reject h0, so residuals are indep

# additive
# check for autocorrelation in residuals
Box.test(residuals_hw2, lag = 10, type = "Ljung-Box") # h0 res indep

    Box-Ljung test

data:  residuals_hw2
X-squared = 10.493, df = 10, p-value = 0.3983
# p-val > alpha =>  Dont reject h0, so residuals are indep

Multiplicative model follows the data better and has slightly better residuals

# forecast
# save the forecast of the second model
forecast_hw1 <- forecast(hw1_m, h=12)
forecast_hw2 <- forecast(hw2_m, h=12)

# Forecast plot
# Plot the time series with both forecasts
autoplot(sales_m_ts) +
  autolayer(forecast_hw1$mean, series="Additive Holt-Winters Forecast", PI=F) +
  autolayer(forecast_hw2$mean, series="Multiplicative Holt-Winters Forecast", PI=F) +
  ggtitle("Sales Forecast with Holt-Winters Models") +
  xlab("Time") +
  ylab("Sales") +
  scale_color_manual(
    values=c("Additive Holt-Winters Forecast" = "blue",
             "Multiplicative Holt-Winters Forecast" = "red")
  ) +
  theme_minimal() +
  theme(legend.position = "top", legend.title = element_blank())
Warning: Ignoring unknown parameters: `PI`Warning: Ignoring unknown parameters: `PI`

# RMSE Calculation for Holt-Winters models
rmse_hw1 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_hw1)
rmse_hw2 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_hw2)

# Print RMSE values
cat("RMSE for Additive Holt-Winters Model:", rmse_hw1, "\n")
RMSE for Additive Holt-Winters Model: 14123520 
cat("RMSE for Multiplicative Holt-Winters Model:", rmse_hw2, "\n")
RMSE for Multiplicative Holt-Winters Model: 13169921 

Multiplicative model is better

The Holt winters model has a frequency limit of 24, so we cannot do larger than that. Weekly and daily data have 52 and 365 frequencies respectively so we cannot fit the model with the R implementation so far.

ARIMA models

ARIMA is a acronym for Auto Regressive Integrated Moving Average, ARIMA (p,d,q) where p refers to the AR part, q refers to the MA part and d is the degree of first difference involved.

First we nwwd to check if the series is stationary

# see if series is stationary
adf.test(sales_m_ts) #H0, series is non-stationary
# p-val > 0.05 => dont reject, non stationary: series is not stationary
adf.test(diff(sales_m_ts)) #H0, series is non-stationary

# see the acf and pacf
tsdisplay(diff(sales_m_ts))

Monthly sales

plot(sales_m_ts)

ndiffs(sales_m_ts)
[1] 1
tsdisplay(diff(sales_m_ts))

Correlogram plot maybe suggests AR-1 or MA-1 after first difference

# ARIMA(p,d,q) = (1,1,0)
arima1_m<- Arima(sales_m_ts, order=c(1,1,0))
summary(arima1_m)
Series: sales_m_ts 
ARIMA(1,1,0) 

Coefficients:
          ar1
      -0.3178
s.e.   0.1783

sigma^2 = 2.666e+14:  log likelihood = -630.5
AIC=1265   AICc=1265.38   BIC=1268.11

Training set error measures:
                  ME     RMSE      MAE      MPE     MAPE
Training set 4664178 15867282 12399192 6.652001 14.52265
                  MASE        ACF1
Training set 0.3786368 -0.07165611
# study residual to see if is a good model
resid1_m<- residuals(arima1_m)
tsdisplay(resid1_m)

Residuals look stationary after fitting ARIMA

auto_arima_m <- auto.arima(sales_m_ts)
auto_arima_m
Series: sales_m_ts 
ARIMA(0,1,1) with drift 

Coefficients:
          ma1    drift
      -0.3741  3475637
s.e.   0.1604  1659940

sigma^2 = 2.494e+14:  log likelihood = -628.83
AIC=1263.66   AICc=1264.44   BIC=1268.33
autoplot(forecast(auto_arima_m))

checkresiduals(auto_arima_m)

    Ljung-Box test

data:  Residuals from ARIMA(0,1,1) with drift
Q* = 0.42136, df = 6, p-value = 0.9987

Model df: 1.   Total lags used: 7

The residuals of the Autoarima look stationary

AIC of the the manual arima is 1265, while the one of the autoarima is 1263. Lets use the autoarima

# Fitted values from both models
fitted_auto_arima <- fitted(auto_arima_m)
fitted_arima1 <- fitted(arima1_m)

# Create a data frame for plotting
plot_data <- data.frame(
  Time = time(sales_m_ts),
  Actual = as.numeric(sales_m_ts),
  Fitted_Auto_ARIMA = as.numeric(fitted_auto_arima),
  Fitted_ARIMA1 = as.numeric(fitted_arima1)
)

# Melt the data frame
plot_data_melted <- melt(plot_data, id.vars = "Time", 
                         variable.name = "Series", 
                         value.name = "Value")

# Plot

ggplot(plot_data_melted, aes(x = Time, y = Value, color = Series)) +
  geom_point(data = subset(plot_data_melted, Series == "Actual"), size = 2) +  # Actual values as points
  geom_line(data = subset(plot_data_melted, Series != "Actual"), size = 1) +   # Fitted values as lines
  labs(
    title = "Actual vs Fitted Values for ARIMA Models",
    x = "Time",
    y = "Sales",
    color = "Series"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Fitted_Auto_ARIMA" = "blue", "Fitted_ARIMA1" = "red"),
    labels = c("Actual", "Fitted (Auto ARIMA)", "Fitted (ARIMA(1,1,0))")
  ) +
  theme_minimal() +
  theme(
    legend.position = "top",
    legend.title = element_blank()
  )

NA
NA
# Calculate RMSE for the fitted values
# Calculate RMSE for each model
rmse_auto_arima <- calculate_rmse(observed = sales_m_ts, predicted = fitted_auto_arima)
rmse_arima1 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_arima1)

# Print RMSE values
cat("RMSE for Auto ARIMA Model:", rmse_auto_arima, "\n")
RMSE for Auto ARIMA Model: 15118942 
cat("RMSE for ARIMA(1,1,0) Model:", rmse_arima1, "\n")
RMSE for ARIMA(1,1,0) Model: 15867282 

The RMSE of the Autoarima is better as is the AIC.

The ARIMA(0,1,1) model can be described simply as a random walk with drift. Here’s what that means:

  1. AR (AutoRegressive) Part:

    • The first number, 0, indicates the order of the autoregressive part. In this case, it means there are no autoregressive terms (i.e., the model does not use past values of the series to predict future values).
  2. I (Integrated) Part:

    • The second number, 1, indicates the degree of differencing required to make the time series stationary. Differencing is a technique used to remove trends and seasonality from the series. A value of 1 means the series is differenced once.
  3. MA (Moving Average) Part:

    • The third number, 1, indicates the order of the moving average part.

An ARIMA(0,1,1) model is suitable when:

The d=1 parameter in ARIMA(0,1,1) indicates that the series is differenced once to achieve stationarity. Before differencing, the series may exhibit a linear trend or random walk behavior. After differencing, the series should show no trend and have relatively stable mean and variance

The q=1 in ARIMA(0,1,1) indicates that the series is modeled with a first-order moving average component after differencing. The autocorrelation function (ACF) of the differenced series should show: A significant spike at lag 1. Rapid decay to zero after lag 1. The partial autocorrelation function (PACF) should show no significant lags.

# study residual to see if is a good model
resid_autoarima_m<- residuals(auto_arima_m)
tsdisplay(resid_autoarima_m)

Weekly sales

# see if series is stationary
adf.test(sales_w_ts) #H0, series is non-stationary

    Augmented Dickey-Fuller Test

data:  sales_w_ts
Dickey-Fuller = -2.9189, Lag order = 5, p-value = 0.1934
alternative hypothesis: stationary
# p-val > 0.05 => dont reject, non stationary: series is not stationary
adf.test(diff(sales_w_ts)) # after diff is sationary
Warning: p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  diff(sales_w_ts)
Dickey-Fuller = -6.5436, Lag order = 5, p-value = 0.01
alternative hypothesis: stationary

After differencing, looks stationary

tsdisplay(diff(sales_w_ts))

Correlograms suggest maybe AR 1 or MA 1.

### Manual ARIMA------------
# ARIMA(p,d,q) = (1,1,0)
arima1_w<- Arima(sales_w_ts, order=c(1,1,0))
summary(arima1_w)
Series: sales_w_ts 
ARIMA(1,1,0) 

Coefficients:
          ar1
      -0.4400
s.e.   0.0749

sigma^2 = 1.17e+13:  log likelihood = -2502.2
AIC=5008.4   AICc=5008.48   BIC=5014.45

Training set error measures:
                   ME    RMSE     MAE        MPE     MAPE
Training set 159889.8 3398717 2549146 -0.9012317 12.90507
                  MASE        ACF1
Training set 0.3542043 -0.04856579
auto_arima_w <- auto.arima(sales_w_ts)
summary(auto_arima_w)
Series: sales_w_ts 
ARIMA(0,1,1) 

Coefficients:
          ma1
      -0.5454
s.e.   0.0763

sigma^2 = 1.13e+13:  log likelihood = -2499.58
AIC=5003.15   AICc=5003.23   BIC=5009.2

Training set error measures:
                   ME    RMSE     MAE        MPE     MAPE
Training set 294210.8 3339058 2474168 -0.2764229 12.33848
                  MASE         ACF1
Training set 0.3437861 -0.008618996

AIC on the Autoarima is better, lets go with that one

checkresiduals(auto_arima_w)

    Ljung-Box test

data:  Residuals from ARIMA(0,1,1)
Q* = 18.205, df = 30, p-value = 0.9551

Model df: 1.   Total lags used: 31

Residuals look stationary, see the plots for both models

# Fit ARIMA models for weekly data
arima1_w <- Arima(sales_w_ts, order = c(1, 1, 0))
auto_arima_w <- auto.arima(sales_w_ts)

# Extract fitted values for both models
fitted_arima1_w <- fitted(arima1_w)
fitted_auto_arima_w <- fitted(auto_arima_w)

# Create a data frame for plotting
plot_data <- data.frame(
  Time = time(sales_w_ts),
  Actual = as.numeric(sales_w_ts),
  Fitted_ARIMA1 = as.numeric(fitted_arima1_w),
  Fitted_Auto_ARIMA = as.numeric(fitted_auto_arima_w)
)

# Melt the data frame for ggplot2
plot_data_melted <- melt(plot_data, id.vars = "Time", 
                         variable.name = "Series", 
                         value.name = "Value")

# Plot using ggplot2
ggplot(plot_data_melted, aes(x = Time, y = Value, color = Series)) +
  geom_point(data = subset(plot_data_melted, Series == "Actual"), size = 2) +  # Actual values as points
  geom_line(data = subset(plot_data_melted, Series != "Actual"), size = 1) +   # Fitted values as lines
  labs(
    title = "Actual vs Fitted Values for ARIMA Models (Weekly)",
    x = "Time",
    y = "Sales",
    color = "Series"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Fitted_ARIMA1" = "red", "Fitted_Auto_ARIMA" = "blue"),
    labels = c("Actual", "Fitted (ARIMA(1,1,0))", "Fitted (Auto ARIMA)")
  ) +
  theme_minimal() +
  theme(
    legend.position = "top",
    legend.title = element_blank()
  )

# Calculate RMSE for both models
rmse_arima1_w <- calculate_rmse(observed = sales_w_ts, predicted = fitted_arima1_w)
rmse_auto_arima_w <- calculate_rmse(observed = sales_w_ts, predicted = fitted_auto_arima_w)

# Print RMSE values
cat("RMSE for ARIMA(1,1,0) Model (Weekly):", rmse_arima1_w, "\n")
RMSE for ARIMA(1,1,0) Model (Weekly): 3398717 
cat("RMSE for Auto ARIMA Model (Weekly):", rmse_auto_arima_w, "\n")
RMSE for Auto ARIMA Model (Weekly): 3339058 

The Auto-arima is also better in terms of RMSE

Daily sales

# see if series is stationary
adf.test(sales_d_ts) #H0, series is non-stationary
# p-val < 0.05 =>  reject non stationary: series might be stationary

No need for differencing because is already stationary, try to model with arima

tsdisplay(sales_d_ts)

Autocorrelograms are not easy to interpret, but lets try with a baseline model

# ARIMA(p,d,q) = (2,1,0)
arima1_d<- Arima(sales_d_ts, order=c(1,0,1))
summary(arima1_d)
checkresiduals(arima1_d)

Residuals look not entirely stationary

Try to model with automatic approach:

auto_arima_d <- auto.arima(sales_d_ts)
summary(auto_arima_d)
checkresiduals(auto_arima_d)

Rresiduals improve, and AIC is lower in the autoarima Check the fit for both models

# Extract fitted values for both models
fitted_arima1_d <- fitted(arima1_d)
fitted_auto_arima_d <- fitted(auto_arima_d)

# Create a data frame for plotting
plot_data <- data.frame(
  Time = time(sales_d_ts),
  Actual = as.numeric(sales_d_ts),
  Fitted_ARIMA1 = as.numeric(fitted_arima1_d),
  Fitted_Auto_ARIMA = as.numeric(fitted_auto_arima_d)
)

# Melt the data frame for ggplot2
plot_data_melted <- melt(plot_data, id.vars = "Time", 
                         variable.name = "Series", 
                         value.name = "Value")

# Plot using ggplot2
ggplot(plot_data_melted, aes(x = Time, y = Value, color = Series)) +
  geom_point(data = subset(plot_data_melted, Series == "Actual"), size = 2) +  # Actual values as points
  geom_line(data = subset(plot_data_melted, Series != "Actual"), size = 1) +   # Fitted values as lines
  labs(
    title = "Actual vs Fitted Values for ARIMA Models (Daily)",
    x = "Time",
    y = "Sales",
    color = "Series"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Fitted_ARIMA1" = "red", "Fitted_Auto_ARIMA" = "blue"),
    labels = c("Actual", "Fitted (ARIMA(1,0,1))", "Fitted (Auto ARIMA)")
  ) +
  theme_minimal() +
  theme(
    legend.position = "top",
    legend.title = element_blank()
  )

Plot is not readable, but check the RMSE for both models to confirm wihch fits better

# Calculate RMSE for both models
rmse_arima1_d <- calculate_rmse(observed = sales_d_ts, predicted = fitted_arima1_d)
rmse_auto_arima_d <- calculate_rmse(observed = sales_d_ts, predicted = fitted_auto_arima_d)

# Print RMSE values
cat("RMSE for ARIMA(1,0,1) Model (Daily):", rmse_arima1_d, "\n")
cat("RMSE for Auto ARIMA Model (Daily):", rmse_auto_arima_d, "\n")

Autoarima is much better, now try to improve with seasonality, beacuse daily data looks seasonal each 7 days.

SARIMA

# Daily sales
tsdisplay(sales_d_ts) # 
tsdisplay(diff(sales_d_ts))
sarima_d <- auto.arima(sales_d_ts, seasonal=TRUE)
summary(sarima_d)
resid_ds<- residuals(sarima_d)
tsdisplay(resid_ds)

# check for autocorrelation
Box.test(residuals(sarima_d), type="Ljung-Box")
# A low p-value (<0.05) suggests residual autocorrelation.

Looks like Aarima is the same in terms of AIC, lets check the RMSE:

# Extract fitted values for both models

fitted_sarima_d <- fitted(sarima_d)

# Calculate RMSE for both models
rmse_sarima_d <- calculate_rmse(observed = sales_d_ts, predicted = fitted_sarima_d)

# Print RMSE values
cat("RMSE for Auto ARIMA Model (Daily):", rmse_auto_arima_d, "\n")
cat("RMSE for Seasonal ARIMA Model (Daily):", rmse_sarima_d, "\n")

The RMSE is exactly the same, they are the same model.

SARIMAX

Refine SARIMA with external regressors

# readefine sales_d_ts
head(df_merged_d)
sales_d_ts <- ts(exp(df_merged_d$sales_cop), frequency=365, start=c(2021, 334))  # 334 is November 30
seasonal_sales_d_ts <- ts(exp(df_merged_d$sales_cop), frequency=7, start=c(2021, 334))  # 334 is November 30
plot(sales_d_ts)
tsdisplay(sales_d_ts,lag.max = 30)
tsdisplay(seasonal_sales_d_ts,lag.max = 30)
# define regresors
# Select specific columns by name
x_regressors_d <- df_merged_d %>% select(rain_sum, fx, tmedian)
# Apply the exponential function to each column
x_regressors_d <- as.data.frame(apply(x_regressors_d, 2, exp))
# Convert to a matrix for ARIMA modeling
x_regressors_d <- as.matrix(x_regressors_d)
# fit the model on sales
# Fit an auto.arima model with seasonal component and external regressors
sarimax_model_d <- auto.arima(
  sales_d_ts,
  seasonal = TRUE,               # Enable seasonal components
  xreg = x_regressors_d          # External regressors
)

# Display the summary of the fitted model
summary(sarimax_model_d)

The AIC actually decreases, lets check the RMSE

# Extract fitted values for all models
fitted_sarimax_d <- fitted(sarimax_model_d)

# Calculate RMSE for all models
rmse_sarimax_d <- calculate_rmse(observed = sales_d_ts, predicted = fitted_sarimax_d)

# Print RMSE values
cat("RMSE for Auto ARIMA Model (Daily):", rmse_auto_arima_d, "\n")
cat("RMSE for Seasonal ARIMA Model (Daily):", rmse_sarima_d, "\n")
cat("RMSE for SARIMAX Model (Daily):", rmse_sarimax_d, "\n")

The RMSE also worsens, so stay with regular Auto-ARIMA

Exponential Smoothing methods

Simple Exponential Smoothing

Monthly Sales

Monthly Sales

fit_m1 <- ses(sales_m_ts, alpha = 0.2, initial = 'simple', h=5)
fit_m2 <- ses(sales_m_ts, alpha = 0.6, initial = 'simple', h=5)
fit_m3 <- ses(sales_m_ts, h=5)

plot(sales_m_ts, ylab='Monthly Sales', xlab='Months')
lines(fitted(fit_m1), col='blue', type='o')
lines(fitted(fit_m2), col='red', type='o')
lines(fitted(fit_m3), col='green', type='o')

forecast_m1 <- ses(sales_m_ts, h=5)

# Accuracy of one-step-ahead training errors
round(accuracy(forecast_m1),2)
                  ME     RMSE      MAE   MPE MAPE MASE  ACF1
Training set 3207582 17626876 13250973 -12.1 29.7  0.4 -0.05
summary(forecast_m1)

Forecast method: Simple exponential smoothing

Model Information:
Simple exponential smoothing 

Call:
ses(y = sales_m_ts, h = 5)

  Smoothing parameters:
    alpha = 0.675 

  Initial states:
    l = 56978123.3871 

  sigma:  18137906

     AIC     AICc      BIC 
1336.322 1337.072 1341.073 

Error measures:
                  ME     RMSE      MAE       MPE     MAPE
Training set 3207582 17626876 13250973 -12.09656 29.70395
                  MASE       ACF1
Training set 0.4046478 -0.0504105

Forecasts:
autoplot(forecast_m1) + autolayer(fitted(forecast_m1),series='Fitted') + ylab("Monthly Sales")+xlab("Months")

# Extract fitted values for each model
fitted_m1 <- fitted(fit_m1)
fitted_m2 <- fitted(fit_m2)
fitted_m3 <- fitted(fit_m3)

# Calculate RMSE for each model
rmse_m1 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_m1)
rmse_m2 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_m2)
rmse_m3 <- calculate_rmse(observed = sales_m_ts, predicted = fitted_m3)

# Print RMSE values
cat("RMSE for SES Model 1 (alpha = 0.2):", rmse_m1, "\n")
RMSE for SES Model 1 (alpha = 0.2): 23924620 
cat("RMSE for SES Model 2 (alpha = 0.6):", rmse_m2, "\n")
RMSE for SES Model 2 (alpha = 0.6): 16189623 
cat("RMSE for SES Model 3 (Optimized alpha):", rmse_m3, "\n")
RMSE for SES Model 3 (Optimized alpha): 17626876 
rmse_exp_sm_m <- rmse_m2
Weekly Sales

Weekly Sales

For weekly data, exponential smoothing can capture longer-term trends and seasonal patterns that repeat on a weekly basis. Weekly data can also have seasonal components related to months, quarters, or years.

fit_w1 <- ses(sales_w_ts, alpha = 0.2, initial = 'simple', h=5)
fit_w2 <- ses(sales_w_ts, alpha = 0.6, initial = 'simple', h=5)
fit_w3 <- ses(sales_w_ts, h=5)

plot(sales_w_ts, ylab='Weekly Sales', xlab='Weeks')
lines(fitted(fit_w1), col='blue', type='o')
lines(fitted(fit_w2), col='red', type='o')
lines(fitted(fit_w3), col='green', type='o')

forecast_w1 <- ses(sales_w_ts, h=5)
round(accuracy(forecast_w1),2)
                   ME    RMSE     MAE   MPE  MAPE MASE ACF1
Training set 287718.1 3340420 2478696 -0.46 12.47 0.34    0
summary(forecast_w1)

Forecast method: Simple exponential smoothing

Model Information:
Simple exponential smoothing 

Call:
ses(y = sales_w_ts, h = 5)

  Smoothing parameters:
    alpha = 0.4505 

  Initial states:
    l = 6860998.2575 

  sigma:  3362470

     AIC     AICc      BIC 
5372.269 5372.430 5381.360 

Error measures:
                   ME    RMSE     MAE        MPE    MAPE
Training set 287718.1 3340420 2478696 -0.4614222 12.4674
                  MASE         ACF1
Training set 0.3444153 -0.004238849

Forecasts:
autoplot(forecast_w1) + autolayer(fitted(forecast_w1),series='Fitted') + ylab("Weekly Sales")+xlab("Weeks")

# Extract fitted values for each model
fitted_w1 <- fitted(fit_w1)
fitted_w2 <- fitted(fit_w2)
fitted_w3 <- fitted(fit_w3)

# Calculate RMSE for each model
rmse_w1 <- calculate_rmse(observed = sales_w_ts, predicted = fitted_w1)
rmse_w2 <- calculate_rmse(observed = sales_w_ts, predicted = fitted_w2)
rmse_w3 <- calculate_rmse(observed = sales_w_ts, predicted = fitted_w3)

# Print RMSE values
cat("RMSE for SES Model 1 (alpha = 0.2):", rmse_w1, "\n")
RMSE for SES Model 1 (alpha = 0.2): 3548490 
cat("RMSE for SES Model 2 (alpha = 0.6):", rmse_w2, "\n")
RMSE for SES Model 2 (alpha = 0.6): 3375868 
cat("RMSE for SES Model 3 (Optimized alpha):", rmse_w3, "\n")
RMSE for SES Model 3 (Optimized alpha): 3340420 
rmse_exp_sm_w <- rmse_w3
Daily sales

Daily Sales

For daily data, exponential smoothing can be used to forecast short-term trends and seasonal patterns. When applying exponential smoothing to daily data, you need to consider:

  • Seasonality: Daily data often exhibit seasonal patterns, such as weekly cycles (e.g., higher sales on weekends).

  • Holidays and special events: These can cause irregular patterns in daily data that may need to be accounted for.


fit_d1 <- ses(sales_d_ts, alpha = 0.2, initial = 'simple', h=5)
fit_d2 <- ses(sales_d_ts, alpha = 0.6, initial = 'simple', h=5)
fit_d3 <- ses(sales_d_ts, h=5)

plot(sales_d_ts, ylab='Daily Sales', xlab='Days')
lines(fitted(fit_d1), col='blue', type='o')
lines(fitted(fit_d2), col='red', type='o')
lines(fitted(fit_d3), col='green', type='o')

forecast_d1 <- ses(sales_d_ts, h=5)
round(accuracy(forecast_d1),2)
                   ME    RMSE     MAE   MPE  MAPE MASE ACF1
Training set 86503.09 1609483 1258308 -67.1 93.29 0.55  0.4
summary(forecast_d1)

Forecast method: Simple exponential smoothing

Model Information:
Simple exponential smoothing 

Call:
ses(y = sales_d_ts, h = 5)

  Smoothing parameters:
    alpha = 0.0393 

  Initial states:
    l = 878511.458 

  sigma:  1611034

     AIC     AICc      BIC 
36920.49 36920.51 36935.32 

Error measures:
                   ME    RMSE     MAE       MPE     MAPE
Training set 86503.09 1609483 1258308 -67.10294 93.28754
                  MASE      ACF1
Training set 0.5505054 0.3989636

Forecasts:
autoplot(forecast_d1) + autolayer(fitted(forecast_d1),series='Fitted') + ylab("Daily Sales")+xlab("Days")

# Extract fitted values for each model
fitted_d1 <- fitted(fit_d1)
fitted_d2 <- fitted(fit_d2)
fitted_d3 <- fitted(fit_d3)

# Calculate RMSE for each model
rmse_d1 <- calculate_rmse(observed = sales_d_ts, predicted = fitted_d1)
rmse_d2 <- calculate_rmse(observed = sales_d_ts, predicted = fitted_d2)
rmse_d3 <- calculate_rmse(observed = sales_d_ts, predicted = fitted_d3)

# Print RMSE values
cat("RMSE for SES Model 1 (alpha = 0.2):", rmse_d1, "\n")
RMSE for SES Model 1 (alpha = 0.2): 1676166 
cat("RMSE for SES Model 2 (alpha = 0.6):", rmse_d2, "\n")
RMSE for SES Model 2 (alpha = 0.6): 1752876 
cat("RMSE for SES Model 3 (Optimized alpha):", rmse_d3, "\n")
RMSE for SES Model 3 (Optimized alpha): 1609483 
rmse_exp_sm_d <- rmse_d3

GGM + SARMAX

Monthly

# GGM part
# Summary of the GGM model
summary(ggm1)  # Assume ggm1_m is the monthly GGM model
Call: ( Guseo Guidolin Model )

  GGM(series = sales_m_ts, mt = "base", display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-27544719  -8809035    742251   -337148   7701034  23238738 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  13318300  on  31  degrees of freedom
 Multiple R-squared:   0.999873  Residual sum of squares:  5.498691e+15
# Predictions using GGM
pred_GGM_m <- predict(ggm1, newx = matrix(1:length(sales_m_ts), ncol = 1))
pred_GGM_m.inst <- make.instantaneous(pred_GGM_m)
# Convert predictions to a time series
start_time_m <- start(sales_m_ts)  # Start time from sales_m_ts
frequency_m <- frequency(sales_m_ts)  # Frequency from sales_m_ts

pred_GGM_m_vec <- unlist(pred_GGM_m.inst)  # Convert predictions to a numeric vector
pred_GGM_m_ts <- ts(pred_GGM_m_vec, start = start_time_m, frequency = frequency_m)
# Plot actual vs GGM predictions
plot(sales_m_ts, type = "b", xlab = "Month", ylab = "Monthly Sales", pch = 16, lty = 3, cex = 0.6)
lines(pred_GGM_m_ts, col = "red", lty = 2)

#### SARIMAX Refinement------------------------

# Get fitted values from the GGM model
fit.sales_m <- fitted(ggm1)

# Check length consistency
if (length(fit.sales_m) != length(sales_m_ts)) {
  stop("fit.sales_m and sales_m_ts lengths do not match")
}
# Scale GGM fitted values and the cumulative sales
fit.sales_m <- scale(fit.sales_m)
sales_m_ts_scaled <- scale(cumsum(sales_m_ts))  # Scale the cumulative sales for convergence
# Fit SARIMAX with GGM fitted values as regressors
sarima_m <- Arima(
  sales_m_ts_scaled,
  order = c(1, 0, 1),
  seasonal = list(order = c(0, 0, 1), period = 12),  # Monthly seasonality
  xreg = fit.sales_m
)

summary(sarima_m)
Series: sales_m_ts_scaled 
Regression with ARIMA(1,0,1)(0,0,1)[12] errors 

Coefficients:
         ar1     ma1     sma1  intercept    xreg
      0.3609  0.2995  -0.1012     0.0002  1.0007
s.e.  0.2233  0.2162   0.1925     0.0028  0.0029

sigma^2 = 9.454e-05:  log likelihood = 118.13
AIC=-224.25   AICc=-221.36   BIC=-214.75

Training set error measures:
                       ME        RMSE         MAE       MPE
Training set 6.956468e-05 0.009022524 0.006945702 -2.619138
                MAPE       MASE       ACF1
Training set 4.22122 0.07700823 0.04863719
# Reverse scaling for fitted cumulative values
fitted_cumulative <- fitted(sarima_m)

scaling_center <- attr(sales_m_ts_scaled, "scaled:center")
scaling_scale <- attr(sales_m_ts_scaled, "scaled:scale")

fitted_cumulative_original <- fitted_cumulative * scaling_scale + scaling_center

# Convert cumulative fitted values to instantaneous values
fitted_instantaneous <- diff(c(fitted_cumulative_original, NA))  # Add NA to align lengths

# Create a time series object for the fitted instantaneous values
fitted_instantaneous_ts <- ts(
  fitted_instantaneous,
  start = start(sales_m_ts),
  frequency = frequency(sales_m_ts)
)
# Plot actual vs fitted instantaneous values
plot(sales_m_ts, type = "p", col = "blue", pch = 16,
     main = "Original vs Fitted Instantaneous Values (Monthly)",
     xlab = "Time", ylab = "Instantaneous Values")
lines(fitted_instantaneous_ts, col = "red", lwd = 3, lty = 1)

# Add legend
legend("bottomright", legend = c("Original sales", "Fitted sales"),
       col = c("blue", "red"), lty = c(NA, 1), pch = c(16, NA), lwd = c(NA, 3))

# Calculate RMSE for fitted_instantaneous_ts against sales_m_ts
rmse_mixture_m <- calculate_rmse(observed = sales_m_ts, predicted = fitted_instantaneous_ts)

# Print the RMSE value
cat("RMSE for Fitted Instantaneous Values (GGM + SARIMAX):", rmse_mixture_m, "\n")
RMSE for Fitted Instantaneous Values (GGM + SARIMAX): 6978426 
resid_mixture_m <- sales_m_ts - fitted_instantaneous_ts
tsdisplay(resid_mixture_m)

Residuals have autocorrelation at lag 1

Weekly

#### GGM-------------------------------

summary(ggm1_w) # this one is best model found
Call: ( Guseo Guidolin Model )

  GGM(series = sales_w_ts, mt = "base", display = T)

Residuals:
      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-31498207  -8733958   2309014    276818   8889298  21142720 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  12329105  on  148  degrees of freedom
 Multiple R-squared:   0.999873  Residual sum of squares:  2.249701e+16
pred_GGM_w<- predict(ggm1_w, newx=matrix(1:length(sales_w_ts), ncol=1))
pred_GGM_w.inst<- make.instantaneous(pred_GGM_w)
# set same timeframe for GGM preds
start_time_w <- start(sales_w_ts)  # Get start time from sales_w_ts
frequency_w <- frequency(sales_w_ts)  # Get frequency from sales_w_ts

# Convert pred_GGM to a numeric vector
pred_GGM_w_vec <- unlist(pred_GGM_w.inst)  # Flatten the list to a numeric vector
# Create the time series for pred_GGM
pred_GGM_w_ts <- ts(pred_GGM_w_vec, start = start_time_w, frequency = frequency_w)


plot(sales_w_ts, type= "b",xlab="Week", ylab="Weekly Sales",  pch=16, lty=3, cex=0.6)
lines(pred_GGM_w_ts, col = "red", lty = 2)

NA
NA
# SARMAX refinement
fit.sales_w <- fitted(ggm1_w)  # Predicted values from the GGM model

if (length(fit.sales_w) != length(sales_w_ts)) {
  stop("fit.sales_w and sales_w_ts lengths do not match")
}
fit.sales_w <- scale(fit.sales_w) # scale regresor to make convergence

sales_w_ts_scaled <- scale(cumsum(sales_w_ts))  # Scale the time series because if not will not reach convergence

sarima_w <- Arima(
  sales_w_ts_scaled, 
  order = c(1, 0, 1), 
  seasonal = list(order = c(0, 0, 1), period = 52), 
  xreg = fit.sales_w # this is the GGM fitted values
)

summary(sarima_w)
Series: sales_w_ts_scaled 
Regression with ARIMA(1,0,1)(0,0,1)[52] errors 

Coefficients:
         ar1     ma1     sma1  intercept    xreg
      0.9351  0.2911  -0.0164     0.0003  0.9995
s.e.  0.0269  0.0625   0.1091     0.0044  0.0038

sigma^2 = 9.19e-06:  log likelihood = 671.32
AIC=-1330.64   AICc=-1330.06   BIC=-1312.45

Training set error measures:
                        ME        RMSE         MAE        MPE
Training set -2.379355e-05 0.002981512 0.002297777 -0.9188761
                 MAPE      MASE      ACF1
Training set 1.382329 0.1077522 0.1024892
# get fitted values
# Extract the fitted cumulative values from the SARIMA model
fitted_cumulative <- fitted(sarima_w)

# Reverse scaling transformation to get fitted cumulative values in the original scale
scaling_center <- attr(sales_w_ts_scaled, "scaled:center")
scaling_scale <- attr(sales_w_ts_scaled, "scaled:scale")

fitted_cumulative_original <- fitted_cumulative * scaling_scale + scaling_center

# Convert cumulative fitted values to instantaneous values
fitted_instantaneous <- diff(c(fitted_cumulative_original, NA))  # Add NA to align lengths

# Create a time series object for the fitted instantaneous values
fitted_instantaneous_ts <- ts(
  fitted_instantaneous, 
  start = start(sales_w_ts), 
  frequency = frequency(sales_w_ts)
)
# Plot original instantaneous values vs fitted instantaneous values
plot(sales_w_ts, type = "p", col = "blue", pch = 16,
     main = "Original vs Fitted Instantaneous Values",
     xlab = "Time", ylab = "Instantaneous Values")

# Add the fitted instantaneous values as a line
lines(fitted_instantaneous_ts, col = "red", lwd = 3, lty = 1)

# Add legend
legend("bottomright", legend = c("Original Instantaneous", "Fitted Instantaneous"),
       col = c("blue", "red"), lty = c(NA, 1), pch = c(16, NA), lwd = c(NA, 3))

# Residuals
# Step 1: Extract residuals from the SARIMA model
resid_w <- residuals(sarima_w)

# Step 2: Visualize residuals
# Time series plot of residuals
tsdisplay(resid_w, main = "Residual Diagnostics for SARIMA Model")


# Step 3: Test residuals for stationarity
adf_test <- adf.test(resid_w)
Warning: p-value smaller than printed p-value
cat("ADF Test p-value:", adf_test$p.value, "\n")
ADF Test p-value: 0.01 
if (adf_test$p.value < 0.05) {
  cat("The residuals are stationary.\n")
} else {
  cat("The residuals are not stationary.\n")
}
The residuals are stationary.
# Step 4: Test residuals for white noise (no autocorrelation)

ljung_box_test <- Box.test(resid_w, lag = 20, type = "Ljung-Box")
cat("Ljung-Box Test p-value:", ljung_box_test$p.value, "\n")
Ljung-Box Test p-value: 1.110658e-05 
if (ljung_box_test$p.value > 0.05) {
  cat("The residuals resemble white noise (uncorrelated).\n")
} else {
  cat("The residuals show significant autocorrelation.\n")
}
The residuals show significant autocorrelation.

Stationary residuals but with significant correlation

#### RMSE for SARIMAX Predictions ####
rmse_mixture_w <- calculate_rmse(observed = sales_w_ts, predicted = fitted_instantaneous_ts)

# Print RMSE for SARIMAX
cat("RMSE for SARIMAX Predictions:", rmse_mixture_w, "\n")
RMSE for SARIMAX Predictions: 1202671 

Daily

# Scaling the sales data
sales_min <- min(sales_d_ts)
sales_max <- max(sales_d_ts)
sales_scaled <- (sales_d_ts - sales_min) / (sales_max - sales_min)

# View scaled data
summary(sales_scaled)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.1911  0.2868  0.3219  0.4343  1.0000 
plot(sales_scaled, type = "l", main = "Scaled Daily Sales", xlab = "Day", ylab = "Scaled Sales")


#### GGM-------------------------------
# Fit GGM model using scaled data
ggm1_d <- GGM(sales_scaled, mt = 'base', display = T)
Warning: NaNs producedWarning: NaNs producedWarning: NaNs produced

summary(ggm1_d)
Call: ( Guseo Guidolin Model )

  GGM(series = sales_scaled, mt = "base", display = T)

Residuals:
     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-3.40209 -0.89405  0.18000  0.03836  0.97389  2.48042 

Coefficients:
 
---
 Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

 Residual standard error  1.199911  on  1034  degrees of freedom
 Multiple R-squared:   0.999863  Residual sum of squares:  1488.74
# Predictions using GGM
pred_GGM_d <- predict(ggm1_d, newx = matrix(1:length(sales_scaled), ncol = 1))
pred_GGM_d.inst <- make.instantaneous(pred_GGM_d)

# Convert predictions to a time series
start_time_d <- start(sales_scaled)  # Start time from scaled sales
frequency_d <- frequency(sales_scaled)  # Frequency from scaled sales

pred_GGM_d_vec <- unlist(pred_GGM_d.inst)  # Convert predictions to a numeric vector
pred_GGM_d_ts <- ts(pred_GGM_d_vec, start = start_time_d, frequency = frequency_d)

# Plot scaled GGM predictions
plot(sales_scaled, type = "b", xlab = "Day", ylab = "Scaled Daily Sales", pch = 16, lty = 3, cex = 0.6)
lines(pred_GGM_d_ts, col = "red", lty = 2)


#### SARIMAX Refinement------------------------

# Use instantaneous fitted values from the GGM model
fit.sales_d_instantaneous <- pred_GGM_d.inst

# Ensure lengths match
if (length(fit.sales_d_instantaneous) != length(sales_scaled)) {
  stop("Instantaneous fitted values and scaled sales data lengths do not match!")
}

# Fit SARIMAX with instantaneous GGM fitted values as regressors
sarima_d <- auto.arima(
  sales_scaled,
  seasonal = TRUE,                 # Enable seasonal components
  xreg = fit.sales_d_instantaneous, # Use instantaneous GGM values as regressors
  stepwise = TRUE,                 # Enable stepwise selection (faster)
  approximation = FALSE            # Use exact maximum likelihood
)

summary(sarima_d)
Series: sales_scaled 
Regression with ARIMA(2,0,2) errors 

Coefficients:
         ar1      ar2      ma1     ma2    xreg
      1.2120  -0.9762  -1.0599  0.7847  1.0033
s.e.  0.0088   0.0082   0.0296  0.0233  0.0102

sigma^2 = 0.01321:  log likelihood = 774.91
AIC=-1537.82   AICc=-1537.73   BIC=-1508.14

Training set error measures:
                       ME     RMSE        MAE  MPE MAPE
Training set 2.328979e-07 0.114653 0.08637051 -Inf  Inf
                  MASE     ACF1
Training set 0.3897133 0.146021
# Extract fitted scaled values from the SARIMAX model
fitted_scaled <- fitted(sarima_d)

# Reverse scaling for final fitted instantaneous values
fitted_instantaneous_ts <- fitted_scaled * (sales_max - sales_min) + sales_min

# Reverse scaling for GGM predictions
pred_GGM_d_original <- pred_GGM_d_ts * (sales_max - sales_min) + sales_min

# Plot actual vs fitted instantaneous values
plot(sales_d_ts, type = "p", col = "blue", pch = 16,
     main = "Original vs Fitted Instantaneous Values (Daily)",
     xlab = "Time", ylab = "Instantaneous Values")
lines(fitted_instantaneous_ts, col = "red", lwd = 3, lty = 1)

# Add legend
legend("topright", legend = c("Original Instantaneous", "Fitted Instantaneous"),
       col = c("blue", "red"), lty = c(NA, 1), pch = c(16, NA), lwd = c(NA, 3))

#### Residuals-----------------------
# Extract residuals from the SARIMA model
resid_d <- residuals(sarima_d)

# Visualize residuals
tsdisplay(resid_d, main = "Residual Diagnostics for SARIMA Model")


# Test residuals for stationarity
adf_test <- adf.test(resid_d)
Warning: p-value smaller than printed p-value
cat("ADF Test p-value:", adf_test$p.value, "\n")
ADF Test p-value: 0.01 
if (adf_test$p.value < 0.05) {
  cat("The residuals are stationary.\n")
} else {
  cat("The residuals are not stationary.\n")
}
The residuals are stationary.
# Test residuals for white noise (no autocorrelation)
ljung_box_test <- Box.test(resid_d, lag = 20, type = "Ljung-Box")
cat("Ljung-Box Test p-value:", ljung_box_test$p.value, "\n")
Ljung-Box Test p-value: 0 
if (ljung_box_test$p.value > 0.05) {
  cat("The residuals resemble white noise (uncorrelated).\n")
} else {
  cat("The residuals show significant autocorrelation.\n")
}
The residuals show significant autocorrelation.
#### RMSE for SARIMAX Predictions ####
rmse_mixture_d <- calculate_rmse(observed = sales_d_ts, predicted = fitted_instantaneous_ts)

# Print RMSE for SARIMAX
cat("RMSE for SARIMAX Predictions:", rmse_mixture_d, "\n")
RMSE for SARIMAX Predictions: 1182471 

Prophet

This model was introduced by Facebook (S. J. Taylor & Letham, 2018), originally for forecasting daily data with weekly and yearly seasonality, plus holiday effects. It was later extended to cover more types of seasonal data. It works best with time series that have strong seasonality and several seasons of historical data.

Prophet can be considered a nonlinear regression model (Chapter 7), of the form yt=g(t)+s(t)+h(t)+εt, where g(t) describes a piecewise-linear trend (or “growth term”), s(t) describes the various seasonal patterns, h(t) captures the holiday effects, and εt is a white noise error term.

  • The knots (or changepoints) for the piecewise-linear trend are automatically selected if not explicitly specified. Optionally, a logistic function can be used to set an upper bound on the trend.

  • The seasonal component consists of Fourier terms of the relevant periods. By default, order 10 is used for annual seasonality and order 3 is used for weekly seasonality.

  • Holiday effects are added as simple dummy variables.

  • The model is estimated using a Bayesian approach to allow for automatic selection of the changepoints and other model characteristics.

library(prophet)

The input to Prophet is always a dataframe with two columns: ds and y . The ds (datestamp) column should be of a format, ideally YYYY-MM-DD for a date or YYYY-MM-DD HH:MM:SS for a timestamp. The y column must be numeric, and represents the measurement we wish to forecast.

Monthly sales

# sales montly
ggplot(df_merged_m, aes(x=month, y=sales_m)) +
  geom_line() + ggtitle("Monthly Sales of Restaurant")


head(df_merged_m)
#Prophet model
# model with no seasonality
df_prophet_m <- df_merged_m[1:2]
head(df_prophet_m)
colnames(df_prophet_m) = c("ds", "y")
df_prophet_m$y <- exp(df_prophet_m$y)
prophet_sales_m <- prophet(df_prophet_m)
Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
head(df_prophet_m)
# Step 2: Create a future dataframe for the next 14 months
future_sales_m <- make_future_dataframe(
  prophet_sales_m,
  periods = 14,           # Forecast for 14 months
  freq = 'month',         # Monthly frequency
  include_history = TRUE  # Include historical data in the future dataframe
)
tail(future_sales_m)
forecast_sales_m <- predict(prophet_sales_m, future_sales_m)
tail(forecast_sales_m[c('ds', 'yhat', 'yhat_lower', 'yhat_upper')])

plot(prophet_sales_m, forecast_sales_m)

prophet_plot_components(prophet_sales_m, forecast_sales_m)

dyplot.prophet(prophet_sales_m, forecast_sales_m)
#Use the original dataframe to get the fitted values
fitted_values <- predict(prophet_sales_m, df_prophet_m)

# Extract the fitted values (column 'yhat' contains the fitted values)
fitted_y <- fitted_values$yhat

# Calculate RMSE

actual_y <- df_prophet_m$y  # Actual sales values
rmse_prophet_m <- calculate_rmse(observed = actual_y, predicted = fitted_y)

# Print RMSE
cat("RMSE for Prophet Fitted Values:", rmse_prophet_m, "\n")
RMSE for Prophet Fitted Values: 16786939 

Residuals for prophet

# Calculate Residuals
residuals_prophet <- actual_y - fitted_y  # Residuals = Actual - Fitted

#  Visualize Residuals using tsdisplay

tsdisplay(residuals_prophet, main = "Residual Diagnostics for Prophet Model")


#  Perform ADF Test for Stationarity

adf_test <- adf.test(residuals_prophet)
cat("ADF Test p-value:", adf_test$p.value, "\n")
ADF Test p-value: 0.3278912 
if (adf_test$p.value < 0.05) {
  cat("Residuals are stationary (reject H0).\n")
} else {
  cat("Residuals are not stationary (fail to reject H0).\n")
}
Residuals are not stationary (fail to reject H0).
#  Perform Serial Correlation Test
ljung_box_test <- Box.test(residuals_prophet, lag = 10, type = "Ljung-Box")
cat("Ljung-Box Test p-value:", ljung_box_test$p.value, "\n")
Ljung-Box Test p-value: 6.527107e-10 
if (ljung_box_test$p.value > 0.05) {
  cat("Residuals resemble white noise (no significant autocorrelation).\n")
} else {
  cat("Residuals show significant autocorrelation.\n")
}
Residuals show significant autocorrelation.

Weekly sales

ggplot(df_merged_w, aes(x=week, y=sales_w)) +
  geom_line() + ggtitle("Weekly Sales of Restaurant")

head(df_merged_w)
#Prophet model
# model with no seasonality
df_prophet_w <- df_merged_w[1:2]
colnames(df_prophet_w) = c("ds", "y")
df_prophet_w$y <- exp(df_prophet_w$y)
df_prophet_w


prophet_sales_w <- prophet(df_prophet_w)
Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.

Predictions are made on a dataframe with a column ds containing the dates for which predictions are to be made. The make_future_dataframe function takes the model object and a number of periods to forecast and produces a suitable dataframe. By default it will also include the historical dates so we can evaluate in-sample fit.

future_sales_w <- make_future_dataframe(prophet_sales_w, 
                                        periods = 52,
                                        freq = 'week',
                                        include_history = T)
tail(future_sales_w)

As with most modeling procedures in R, we use the generic predict function to get our forecast. The forecast object is a dataframe with a column yhat containing the forecast. It has additional columns for uncertainty intervals and seasonal components.

# R
forecast_sales_w <- predict(prophet_sales_w, future_sales_w)
tail(forecast_sales_w[c('ds', 'yhat', 'yhat_lower', 'yhat_upper')])
plot(prophet_sales_w, forecast_sales_w)

You can use the prophet_plot_components function to see the forecast broken down into trend, weekly seasonality, and yearly seasonality.

prophet_plot_components(prophet_sales_w, forecast_sales_w)

dyplot.prophet(prophet_sales_w, forecast_sales_w)
# Use the original dataset to get fitted values
fitted_values_w <- predict(prophet_sales_w, df_prophet_w)

# Extract the fitted values (column 'yhat' contains the fitted values)
fitted_y_w <- fitted_values_w$yhat

# Ensure alignment between actual values (y) and fitted values (yhat)
actual_y_w <- df_prophet_w$y  # Actual weekly sales values

# Calculate RMSE for weekly data
rmse_prophet_w <- calculate_rmse(observed = actual_y_w, predicted = fitted_y_w)

# Print RMSE
cat("RMSE for Prophet Fitted Values (Weekly):", rmse_prophet_w, "\n")
RMSE for Prophet Fitted Values (Weekly): 3319446 
# Calculate Residuals
residuals_prophet_w <- actual_y_w - fitted_y_w  # Residuals = Actual - Fitted

# Visualize Residuals using tsdisplay
tsdisplay(residuals_prophet_w, main = "Residual Diagnostics for Weekly Prophet Model")


# Perform ADF Test for Stationarity

adf_test_w <- adf.test(residuals_prophet_w)
cat("ADF Test p-value:", adf_test_w$p.value, "\n")
ADF Test p-value: 0.04400527 
if (adf_test_w$p.value < 0.05) {
  cat("Residuals are stationary (reject H0).\n")
} else {
  cat("Residuals are not stationary (fail to reject H0).\n")
}
Residuals are stationary (reject H0).
# Perform Serial Correlation Test
ljung_box_test_w <- Box.test(residuals_prophet_w, lag = 10, type = "Ljung-Box")
cat("Ljung-Box Test p-value:", ljung_box_test_w$p.value, "\n")
Ljung-Box Test p-value: 7.638334e-14 
if (ljung_box_test_w$p.value > 0.05) {
  cat("Residuals resemble white noise (no significant autocorrelation).\n")
} else {
  cat("Residuals show significant autocorrelation.\n")
}
Residuals show significant autocorrelation.

Daily Sales

head(sales_d_ts)
Time Series:
Start = c(2021, 335) 
End = c(2021, 340) 
Frequency = 365 
[1]  673701 1205301 1340901 1343701  360901  318801
plot(sales_d_ts)

sales_d_values <- as.numeric(sales_d_ts)   # Extract numeric values

df_prophet_d <- data.frame(
  ds = df_merged_d$date,  # Dates
  y = sales_d_values   # Sales values
)
#Prophet model


#prophet_sales_d <- prophet(df_prophet, weekly.seasonality = TRUE)
prophet_sales_d <- prophet(df_prophet_d)
Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
future_sales_d <- make_future_dataframe(prophet_sales_d,
                                        periods = 60,
                                        freq = 'day',
                                        include_history = T)
tail(future_sales_d)
forecast_sales_d <- predict(prophet_sales_d, future_sales_d)
tail(forecast_sales_d[c('ds', 'yhat', 'yhat_lower', 'yhat_upper')])
plot(prophet_sales_d, forecast_sales_d)

prophet_plot_components(prophet_sales_d, forecast_sales_d)

dyplot.prophet(prophet_sales_d, forecast_sales_d)
# Extract fitted values for RMSE calculation
fitted_values_d <- predict(prophet_sales_d, df_prophet_d)

# Extract fitted values (column 'yhat')
fitted_y_d <- fitted_values_d$yhat
actual_y_d <- df_prophet_d$y  # Actual sales values

# Step 8: Calculate RMSE
rmse_prophet_d <- calculate_rmse(observed = actual_y_d, predicted = fitted_y_d)

# Print RMSE
cat("RMSE for Prophet Fitted Values (Daily):", rmse_prophet_d, "\n")
RMSE for Prophet Fitted Values (Daily): 1022726 
# Calculate Residuals
residuals_prophet_d <- actual_y_d - fitted_y_d  # Residuals = Actual - Fitted

# Visualize Residuals using tsdisplay

tsdisplay(residuals_prophet_d, main = "Residual Diagnostics for Daily Prophet Model")


# Perform ADF Test for Stationarity

adf_test_d <- adf.test(residuals_prophet_d)
Warning: p-value smaller than printed p-value
cat("ADF Test p-value:", adf_test_d$p.value, "\n")
ADF Test p-value: 0.01 
if (adf_test_d$p.value < 0.05) {
  cat("Residuals are stationary (reject H0).\n")
} else {
  cat("Residuals are not stationary (fail to reject H0).\n")
}
Residuals are stationary (reject H0).
# Perform Serial Correlation Test
ljung_box_test_d <- Box.test(residuals_prophet_d, lag = 20, type = "Ljung-Box")
cat("Ljung-Box Test p-value:", ljung_box_test_d$p.value, "\n")
Ljung-Box Test p-value: 0 
if (ljung_box_test_d$p.value > 0.05) {
  cat("Residuals resemble white noise (no significant autocorrelation).\n")
} else {
  cat("Residuals show significant autocorrelation.\n")
}
Residuals show significant autocorrelation.
rmse_list <- c(rmse_ols_m, rmse_ols_w, rmse_ols_d,
               rmse_bm_m, rmse_bm_w, rmse_bm_d,
               rmse_ggm1, rmse_ggm_w, rmse_ggm_d,
               rmse_hw2,
               rmse_auto_arima, rmse_auto_arima_w, rmse_auto_arima_d,
               rmse_sarima_d,
               rmse_sarimax_d,
               rmse_exp_sm_m, rmse_exp_sm_w, rmse_exp_sm_m,
               rmse_mixture_m, rmse_mixture_w, rmse_mixture_d,
               rmse_prophet_m, rmse_prophet_w, rmse_prophet_d
               )
rmse_list
 [1] 13229295  3909103  1425907 18498870  4542019  1651896
 [7] 11759505  3488834  1600828 13169921 15118942  3339058
[13]  1094980  1094980  1146332 16189623  3340420 16189623
[19]  6978426  1202671  1182471 16786939  3319446  1022726

Evaluation of all models

# Initialize an empty data frame for RMSE values
rmse_table <- data.frame(
  Model = character(),
  Monthly = numeric(),
  Weekly = numeric(),
  Daily = numeric(),
  stringsAsFactors = FALSE
)

# Monthly RMSE values
rmse_monthly <- c(
  "OLS" = rmse_ols_m,
  "Bass_Model" = rmse_bm_m,
  "GGM" = rmse_ggm1,
  "Holt_Winters" = rmse_hw2,
  "Arima" = rmse_auto_arima,
  "Exp_Smooth" = rmse_exp_sm_m,
  "GGM+SARIMA" = rmse_mixture_m,
  "Prophet" = rmse_prophet_m
)

# Weekly RMSE values
rmse_weekly <- c(
  "OLS" = rmse_ols_w,
  "Bass_Model" = rmse_bm_w,
  "GGM" = rmse_ggm_w,
  "Holt_Winters" = NaN,
  "Arima" = rmse_auto_arima_w,
  "Exp_Smooth" = rmse_exp_sm_w,
  "GGM+SARIMA" = rmse_mixture_w,
  "Prophet" = rmse_prophet_w
)

# Daily RMSE values
rmse_daily <- c(
  "OLS" = rmse_ols_d,
  "Bass_Model" = rmse_bm_d,
  "GGM" = rmse_ggm_d,
  "Holt_Winters" = NaN,
  "Arima" = rmse_auto_arima_d,
  "Exp_Smooth" = rmse_exp_sm_d,
  "GGM+SARIMA" = rmse_mixture_d,
  "Prophet" = rmse_prophet_d
)

# Combine RMSE values into a table
for (model_name in names(rmse_monthly)) {
  rmse_table <- rbind(rmse_table, data.frame(
    Model = model_name,
    Monthly = rmse_monthly[model_name],
    Weekly = rmse_weekly[model_name],
    Daily = rmse_daily[model_name]
  ))
}

# View the RMSE table
print(rmse_table)
NA

Best models are:

  • Monthly: GGM + SARIMA
  • Weekly: GGM + SARIMA
  • Daily: Prophet

Evaluation of best models on Test Set

Import test set

# target variable
test_sales_df <- read_excel("data/sales/test_data.xlsx")
head(test_sales_df)
df_sales_m_test <- test_sales_df %>%
  mutate(month = floor_date(date, "month")) %>% # Extract month
  group_by(month) %>%
  summarise(sales_m = sum(sales_cop), bar_m = sum(bar), food_m = sum(food)
            )     # Summing values

head(df_sales_m_test)
## sales weekly
df_sales_w_test <- test_sales_df %>%
  mutate(week = floor_date(date, "week")) %>% # Extract month
  group_by(week) %>%
  summarise(sales_w = sum(sales_cop), bar_w = sum(bar), food_w = sum(food))     # Summing values

head(df_sales_w_test)

Forecast vs Actual

Montly

cumsum(sales_m_ts)
 [1]    7925601   33539060   65492343  107418523  144885201
 [6]  202811448  282434292  371250728  476444489  569781277
[11]  660649764  762658574  854895801  951384432 1061951572
[16] 1169736471 1296038865 1408776880 1527683850 1642578141
[21] 1761369195 1864564540 1963627555 2050162367 2171930992
[26] 2303345161 2427895903 2547368818 2682080320 2778534518
[31] 2893079374 3002614398 3139212388 3265637545 3369541574
[36] 3515788921
forecast_cumulative
Time Series:
Start = 37 
End = 38 
Frequency = 1 
     [37,]      [38,] 
8217316481 1585965110 

Weekly

Daily

Forecast with Best Models

Montly

Weekly

Daily

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCmVkaXRvcl9vcHRpb25zOiANCiAgbWFya2Rvd246IA0KICAgIHdyYXA6IDcyDQotLS0NCg0KIyBQcm9qZWN0IEJ1c2luZXNzIEVjb25vbWljIGFuZCBGaW5hbmNpYWwgRGF0YQ0KDQojIyBTYWxlcyBvZiBEaW1TdW0gUmVjb3JkcywgQXNpYW4tZm9vZCByZXN0YXVyYW50IGluIE1lZGVsbGluLCBDb2xvbWJpYQ0KDQoyMDI0LzIwMjUNCg0KQXV0aG9yczogRGFuaWVsIEd1dGllcnJleiAmIEZhYmlvIFBpbWVudGVsDQoNCmBgYHtyfQ0KIyBSZXF1aXJlZCBQYWNrYWdlcy0tLS0tLS0tLS0tLS0tLS0tLS0tDQpybShsaXN0ID0gbHMoKSkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShHR2FsbHkpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShmZWFzdHMpDQpsaWJyYXJ5KHRzaWJibGUpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoRElNT1JBKQ0KbGlicmFyeSh0c2VyaWVzKQ0KbGlicmFyeShsbXRlc3QpDQpsaWJyYXJ5KHByb3BoZXQpDQpgYGANCg0KIyMjIEltcG9ydCBEYXRhDQoNCmBgYHtyfQ0KI3NldHdkKCcvVXNlcnMvZmFiaW9waW1lbnRlbC9Eb2N1bWVudHMvUGFkdWEvY2xhc2VzL3NlZ3VuZG8gYW7Mg28gcHJpbWVyIHNlbWVzdHJlL0JFRiBkYXRhL3Byb3llY3RvL3RpbWVfc2VyaWVzX3BhZG92YS1tYWluJykNCg0KIyB0YXJnZXQgdmFyaWFibGUNCnNhbGVzIDwtIHJlYWRfZXhjZWwoImRhdGEvc2FsZXMvc2FsZXNfZGltc3VtXzMxMTAyMDI0Lnhsc3giKQ0KDQpzYWxlc1tpcy5uYShzYWxlcyldIDwtIDAgIyBzZXQgdG8gemVybyBuYSB2YWx1ZXMNCg0KYGBgDQoNCiMjIyBDcmVhdGluZyB2YXJpYWJsZXMNCg0KYGBge3J9DQojIGVjb25vbWljIHZhcmlhYmxlcw0KZWNvX2dyb3d0aCA8LSByZWFkX2V4Y2VsKCJkYXRhL21hY3JvZWNvbm9taWMvZWNvbm9taWNfYWN0aXZpdHkueGxzeCIpDQpmeCA8LSByZWFkX2V4Y2VsKCJkYXRhL21hY3JvZWNvbm9taWMvZngueGxzeCIpICNGb3JlaWduIGV4Y2hhbmdlIGlzIHRoZSBjb252ZXJzaW9uIG9mIG9uZSBjdXJyZW5jeSBpbnRvIGFub3RoZXINCmluZmxhdGlvbiA8LSByZWFkX2V4Y2VsKCJkYXRhL21hY3JvZWNvbm9taWMvaW5mbGF0aW9uLnhsc3giKQ0KdW5lbXBsb3ltZW50IDwtIHJlYWRfZXhjZWwoImRhdGEvbWFjcm9lY29ub21pYy91bmVtcGxveW1lbnQueGxzeCIpDQpgYGANCg0KYGBge3J9DQojIG90aGVyIHZhcmlhYmxlcw0KZ29vZ2xlX3RyZW5kcyA8LSByZWFkX2V4Y2VsKCJkYXRhL290aGVyL2dvb2dsZV90cmVuZHNfcmVzdGF1cmFudGVzLnhsc3giKQ0KcmFpbiA8LSByZWFkX2V4Y2VsKCJkYXRhL290aGVyL3JhaW5fcHJveHkueGxzeCIpDQp0ZW1wIDwtIHJlYWRfZXhjZWwoImRhdGEvb3RoZXIvdGVtcGVyYXR1cmVfZGF0YS54bHN4IikNCnRlbXBbaXMubmEodGVtcCldIDwtIDANCnJhaW5baXMubmEocmFpbildIDwtIDANCnBsb3QodGVtcCR0YXZnKSAjIG5vIHplcm9zIGluIHRlbXAgOiBPSw0KcGxvdCh0ZW1wJHRtZWRpYW4pICMgbm8gemVyb3MgaW4gdGVtcCA6IE9LLSBsb29rcyBiZXR0ZXIgdGhhbiBtZWFuDQpgYGANCg0KIyMjIEV4cGxvcmUgZGF0YSBzdHJ1Y3R1cmUNCg0KYGBge3J9DQpzdHIoc2FsZXMpDQpgYGANCg0KYGBge3J9DQpzdHIoZWNvX2dyb3d0aCkNCmBgYA0KDQpgYGB7cn0NCnN0cihmeCkgIyBGb3JlaWduIGV4Y2hhbmdlIGlzIHRoZSBjb252ZXJzaW9uIG9mIG9uZSBjdXJyZW5jeSBpbnRvIGFub3RoZXINCmBgYA0KDQpgYGB7cn0NCnN0cihpbmZsYXRpb24pDQpgYGANCg0KYGBge3J9DQpzdHIodW5lbXBsb3ltZW50KQ0KYGBgDQoNCmBgYHtyfQ0Kc3RyKGdvb2dsZV90cmVuZHMpDQpgYGANCg0KYGBge3J9DQpzdHIocmFpbikNCmBgYA0KDQpgYGB7cn0NCnN0cih0ZW1wKSAjIHRoaXMgaGFzIE5hTnMsIG11c3QgZmlsbCBzb21laG93DQpgYGANCg0KIyMjIFNhbGVzDQoNCmBgYHtyfQ0KIyBjcmVhdGUgdGltZSB2YXJpYWJsZXMNCnBsb3Qoc2FsZXMkc2FsZXNfY29wKQ0KYGBgDQoNCiMjIyBTYWxlcyBNb250aGx5DQoNCmBgYHtyfQ0KIyBzYWxlcw0KIyMgc2FsZXMgbW9udGhseQ0KZGZfc2FsZXNfbSA8LSBzYWxlcyAlPiUNCiAgbXV0YXRlKG1vbnRoID0gZmxvb3JfZGF0ZShkYXRlLCAibW9udGgiKSkgJT4lICMgRXh0cmFjdCBtb250aA0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShzYWxlc19tID0gc3VtKHNhbGVzX2NvcCksIGJhcl9tID0gc3VtKGJhciksIGZvb2RfbSA9IHN1bShmb29kKQ0KICAgICAgICAgICAgKSAgICAgIyBTdW1taW5nIHZhbHVlcw0KDQpoZWFkKGRmX3NhbGVzX20pDQpgYGANCg0KIyMjIFNhbGVzIFdlZWtseQ0KDQpgYGB7cn0NCiMjIHNhbGVzIHdlZWtseQ0KZGZfc2FsZXNfdyA8LSBzYWxlcyAlPiUNCiAgbXV0YXRlKHdlZWsgPSBmbG9vcl9kYXRlKGRhdGUsICJ3ZWVrIikpICU+JSAjIEV4dHJhY3QgbW9udGgNCiAgZ3JvdXBfYnkod2VlaykgJT4lDQogIHN1bW1hcmlzZShzYWxlc193ID0gc3VtKHNhbGVzX2NvcCksIGJhcl93ID0gc3VtKGJhciksIGZvb2RfdyA9IHN1bShmb29kKSkgICAgICMgU3VtbWluZyB2YWx1ZXMNCg0KaGVhZChkZl9zYWxlc193KQ0KYGBgDQoNCiMjIyBGWA0KDQpgYGB7cn0NCiMgZngNCmRmX2Z4X20gPC0gZnggJT4lDQogIG11dGF0ZShtb250aCA9IGZsb29yX2RhdGUoZGF0ZSwgIm1vbnRoIikpICU+JQ0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShmeF9tID0gbWVhbihmeCkpDQoNCmRmX2Z4X3cgPC0gZnggJT4lDQogIG11dGF0ZSh3ZWVrID0gZmxvb3JfZGF0ZShkYXRlLCAid2VlayIpKSAlPiUNCiAgZ3JvdXBfYnkod2VlaykgJT4lDQogIHN1bW1hcmlzZShmeF93ID0gbWVhbihmeCkpDQoNCmhlYWQoZGZfZnhfbSkNCmhlYWQoZGZfZnhfdykNCmBgYA0KDQojIyMgR29vZ2xlIFRyZW5kcw0KDQpgYGB7cn0NCiMgZ29vZ2xlIHRyZW5kcw0KDQojIG1vbnRseQ0KZGZfZ29vZ2xlX20gPC0gZ29vZ2xlX3RyZW5kcyAlPiUNCiAgbXV0YXRlKG1vbnRoID0gZmxvb3JfZGF0ZShkYXRlLCAibW9udGgiKSkgJT4lDQogIGdyb3VwX2J5KG1vbnRoKSAlPiUNCiAgc3VtbWFyaXNlKGdvb2dsZV9tID0gbWVhbihnb29nbGVfdHJlbmRzKSkNCg0KDQojIHdlZWtseQ0KZGZfZ29vZ2xlX3cgPC0gZ29vZ2xlX3RyZW5kcyAlPiUNCiAgbXV0YXRlKHdlZWsgPSBmbG9vcl9kYXRlKGRhdGUsICJ3ZWVrIikpICU+JQ0KICBncm91cF9ieSh3ZWVrKSAlPiUNCiAgc3VtbWFyaXNlKGdvb2dsZV93ID0gbWVhbihnb29nbGVfdHJlbmRzKSkNCg0KaGVhZChkZl9nb29nbGVfbSkNCmhlYWQoZGZfZ29vZ2xlX3cpDQpgYGANCg0KIyMjIFJhaW4NCg0KYGBge3J9DQojIyByYWluDQpkZl9yYWluX2cgPSByYWluICU+JQ0KICBncm91cF9ieShkYXRlLCByZWdpb24pICU+JQ0KICBzdW1tYXJpc2UocmFpbl9zdW09c3VtKGNvbnRyaWJ1dGlvbl9tM3MpKQ0KDQpkZl9yYWluX2cgIDwtIGRmX3JhaW5fZ1tkZl9yYWluX2ckcmVnaW9uPT0iQU5USU9RVUlBIixdDQoNCmhlYWQoZGZfcmFpbl9nKQ0KDQojIG1vbnRseQ0KZGZfcmFpbl9tIDwtIGRmX3JhaW5fZyAlPiUNCiAgbXV0YXRlKG1vbnRoID0gZmxvb3JfZGF0ZShkYXRlLCAibW9udGgiKSkgJT4lDQogIGdyb3VwX2J5KG1vbnRoKSAlPiUNCiAgc3VtbWFyaXNlKHJhaW5fbSA9IHN1bShyYWluX3N1bSkpDQoNCg0KIyB3ZWVrbHkNCmRmX3JhaW5fdyA8LSBkZl9yYWluX2cgJT4lDQogIG11dGF0ZSh3ZWVrID0gZmxvb3JfZGF0ZShkYXRlLCAid2VlayIpKSAlPiUNCiAgZ3JvdXBfYnkod2VlaykgJT4lDQogIHN1bW1hcmlzZShyYWluX3cgPSBzdW0ocmFpbl9zdW0pKQ0KDQpoZWFkKGRmX3JhaW5fbSkNCmhlYWQoZGZfcmFpbl93KQ0KYGBgDQoNCiMjIyBUZW1wZXJhdHVyZQ0KDQpgYGB7cn0NCiMgdGVtcGVyYXR1cmUNCiMgbW9udGx5DQpkZl90ZW1wX20gPC0gdGVtcCAlPiUNCiAgbXV0YXRlKG1vbnRoID0gZmxvb3JfZGF0ZShkYXRlLCAibW9udGgiKSkgJT4lDQogIGdyb3VwX2J5KG1vbnRoKSAlPiUNCiAgc3VtbWFyaXNlKHRlbXBfbSA9IG1lYW4odGF2ZyksIHByY3BfbSA9IHN1bShwcmNwKSkNCg0KDQojIHdlZWtseQ0KZGZfdGVtcF93IDwtIHRlbXAgJT4lDQogIG11dGF0ZSh3ZWVrID0gZmxvb3JfZGF0ZShkYXRlLCAid2VlayIpKSAlPiUNCiAgZ3JvdXBfYnkod2VlaykgJT4lDQogIHN1bW1hcmlzZSh0ZW1wX3cgPSBtZWFuKHRhdmcpLCBwcmNwX3cgPSBzdW0ocHJjcCkpDQoNCmhlYWQoZGZfdGVtcF9tKQ0KaGVhZChkZl90ZW1wX3cpDQpgYGANCg0KIyMgTWVyZ2luZyBEYXRhIEZyYW1lcw0KDQojIyMjIERhaWx5IERhdGENCg0KYGBge3J9DQojIyBkYWlseSBkYXRhLS0tLS0tLS0tLQ0KI3NhbGVzLCByYWluLCBmeCBhcmUgdGhlIG9ubHkgb25lcyBkYWlseQ0KZGZfbWVyZ2VkX2QgPC0gbWVyZ2Uoc2FsZXMsIGRmX3JhaW5fZywgYnkgPSAiZGF0ZSIsIGFsbCA9IEZBTFNFKSAjIElubmVyIGpvaW4NCmRmX21lcmdlZF9kIDwtIG1lcmdlKGRmX21lcmdlZF9kLCBmeCwgYnkgPSAiZGF0ZSIsIGFsbCA9IEZBTFNFKSAjIElubmVyIGpvaW4NCmRmX21lcmdlZF9kIDwtIG1lcmdlKGRmX21lcmdlZF9kLCB0ZW1wLCBieSA9ICJkYXRlIiwgYWxsID0gRkFMU0UpICMgSW5uZXIgam9pbg0KDQpoZWFkKGRmX21lcmdlZF9kKQ0KDQpgYGANCg0KIyMjIyBXZWVrbHkgRGF0YQ0KDQpgYGB7cn0NCiMjIyB3ZWVrbHkgZGF0YS0tLS0tLS0tLS0NCmRmX21lcmdlZF93IDwtIG1lcmdlKGRmX3NhbGVzX3csIGRmX3JhaW5fdywgYnk9IndlZWsiLCBhbGw9RikNCmRmX21lcmdlZF93IDwtIG1lcmdlKGRmX21lcmdlZF93LCBkZl9nb29nbGVfdywgYnk9IndlZWsiLCBhbGw9RikNCmRmX21lcmdlZF93IDwtIG1lcmdlKGRmX21lcmdlZF93LCBkZl9meF93LCBieT0id2VlayIsIGFsbD1GKQ0KZGZfbWVyZ2VkX3cgPC0gbWVyZ2UoZGZfbWVyZ2VkX3csIGRmX3RlbXBfdywgYnk9IndlZWsiLCBhbGw9RikNCg0KaGVhZChkZl9tZXJnZWRfdykNCmBgYA0KDQojIyMjIE1vbnRobHkgRGF0YQ0KDQpgYGB7cn0NCiMjIyBtb250aGx5IGRhdGEtLS0tLS0tLS0tDQojIGNoYW5nZSBjb2xuYW1lcw0KbmFtZXMoZWNvX2dyb3d0aCkgPC0gYygibW9udGgiLCAiaXNlIikNCm5hbWVzKGluZmxhdGlvbikgPC0gYygibW9udGgiLCAiaW5mbGF0aW9uIikNCm5hbWVzKHVuZW1wbG95bWVudCkgPC0gYygibW9udGgiLCAidW5lbXBsb3ltZW50IikgDQoNCmRmX21lcmdlZF9tIDwtIG1lcmdlKGRmX3NhbGVzX20sIGRmX3JhaW5fbSwgYnk9Im1vbnRoIiwgYWxsPUYpDQpucm93KGRmX21lcmdlZF9tKQ0KDQpkZl9tZXJnZWRfbSA8LSBtZXJnZShkZl9tZXJnZWRfbSwgZGZfZnhfbSwgYnk9Im1vbnRoIiwgYWxsPUYpDQpucm93KGRmX21lcmdlZF9tKQ0KDQpkZl9tZXJnZWRfbSA8LSBtZXJnZShkZl9tZXJnZWRfbSwgZGZfZ29vZ2xlX20sIGJ5PSJtb250aCIsIGFsbD1GKQ0KbnJvdyhkZl9tZXJnZWRfbSkNCg0KZGZfbWVyZ2VkX20gPC0gbWVyZ2UoZGZfbWVyZ2VkX20sIGVjb19ncm93dGgsIGJ5PSJtb250aCIsIGFsbD1GKSAjIG9ubHkgaGFzIHVudGlsIGF1ZyAyMDI0DQpucm93KGRmX21lcmdlZF9tKQ0KDQpkZl9tZXJnZWRfbSA8LSBtZXJnZShkZl9tZXJnZWRfbSwgaW5mbGF0aW9uLCBieT0ibW9udGgiLCBhbGw9RikNCm5yb3coZGZfbWVyZ2VkX20pDQoNCmRmX21lcmdlZF9tIDwtIG1lcmdlKGRmX21lcmdlZF9tLCB1bmVtcGxveW1lbnQsIGJ5PSJtb250aCIsIGFsbD1GKQ0KbnJvdyhkZl9tZXJnZWRfbSkNCg0KZGZfbWVyZ2VkX20gPC0gbWVyZ2UoZGZfbWVyZ2VkX20sIGRmX3RlbXBfbSwgYnk9Im1vbnRoIiwgYWxsPUYpDQpucm93KGRmX21lcmdlZF9tKQ0KYGBgDQoNCiMjIyBFREENCg0KYGBge3J9DQpvYmplY3RzX3RvX2tlZXAgPC0gYygiZGZfbWVyZ2VkX2QiLCAiZGZfbWVyZ2VkX3ciLCAiZGZfbWVyZ2VkX20iKQ0KIyBSZW1vdmUgYWxsIG9iamVjdHMgZXhjZXB0IHRob3NlIHNwZWNpZmllZA0Kcm0obGlzdCA9IHNldGRpZmYobHMoKSwgb2JqZWN0c190b19rZWVwKSkNCmBgYA0KDQojIyMjIERhaWx5IFNhbGVzDQoNCmBgYHtyfQ0KIyBzYWxlcyBkYWlseQ0KZ2dwbG90KA0KICBkZl9tZXJnZWRfZCwgDQogIGFlcyh4PWRhdGUsIHk9c2FsZXNfY29wKQ0KICApICsgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJEYWlseSBTYWxlcyBvZiBSZXN0YXVyYW50IikNCmBgYA0KDQojIyMjIFdlZWtseSBzYWxlcw0KDQpgYGB7cn0NCiMgc2FsZXMgd2Vla2x5DQpnZ3Bsb3QoZGZfbWVyZ2VkX3csIGFlcyh4PXdlZWssIHk9c2FsZXNfdykpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJXZWVrbHkgU2FsZXMgb2YgUmVzdGF1cmFudCIpDQpgYGANCg0KIyMjIyBNb250aGx5IHNhbGVzDQoNCmBgYHtyfQ0KIyBzYWxlcyBtb250bHkNCmdncGxvdChkZl9tZXJnZWRfbSwgYWVzKHg9bW9udGgsIHk9c2FsZXNfbSkpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJNb250aGx5IFNhbGVzIG9mIFJlc3RhdXJhbnQiKQ0KYGBgDQoNCiMjIyMgU3RhY2tlZCBiYXIgcGxvdHMNCg0KV2Ugd2FudCB0byBtb3ZlIHRvIGEgc3RhY2tlZCBiYXIgY2hhcnQgd2hlbiB3ZSBjYXJlIGFib3V0IHRoZSByZWxhdGl2ZQ0KZGVjb21wb3NpdGlvbiBvZiBlYWNoIHByaW1hcnkgYmFyIGJhc2VkIG9uIHRoZSBsZXZlbHMgb2YgYSBzZWNvbmQNCmNhdGVnb3JpY2FsIHZhcmlhYmxlLiBFYWNoIGJhciBpcyBub3cgY29tcHJpc2VkIG9mIGEgbnVtYmVyIG9mIHN1Yi1iYXJzLA0KZWFjaCBvbmUgY29ycmVzcG9uZGluZyB3aXRoIGEgbGV2ZWwgb2YgYSBzZWNvbmRhcnkgY2F0ZWdvcmljYWwgdmFyaWFibGUuDQpUaGUgdG90YWwgbGVuZ3RoIG9mIGVhY2ggc3RhY2tlZCBiYXIgaXMgdGhlIHNhbWUgYXMgYmVmb3JlLCBidXQgbm93IHdlDQpjYW4gc2VlIGhvdyB0aGUgc2Vjb25kYXJ5IGdyb3VwcyBjb250cmlidXRlZCB0byB0aGF0IHRvdGFsLg0KDQpPbmUgaW1wb3J0YW50IGNvbnNpZGVyYXRpb24gaW4gYnVpbGRpbmcgYSBzdGFja2VkIGJhciBjaGFydCBpcyB0byBkZWNpZGUNCndoaWNoIG9mIHRoZSB0d28gY2F0ZWdvcmljYWwgdmFyaWFibGVzIHdpbGwgYmUgdGhlIHByaW1hcnkgdmFyaWFibGUNCihkaWN0YXRpbmcgbWFqb3IgYXhpcyBwb3NpdGlvbnMgYW5kIG92ZXJhbGwgYmFyIGxlbmd0aHMpIGFuZCB3aGljaCB3aWxsDQpiZSB0aGUgc2Vjb25kYXJ5IChkaWN0YXRpbmcgaG93IGVhY2ggcHJpbWFyeSBiYXIgd2lsbCBiZSBzdWJkaXZpZGVkKS4NClRoZSBtb3N0ICdpbXBvcnRhbnQnIHZhcmlhYmxlIHNob3VsZCBiZSB0aGUgcHJpbWFyeTsgdXNlIGRvbWFpbg0Ka25vd2xlZGdlIGFuZCB0aGUgc3BlY2lmaWMgdHlwZSBvZiBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgdG8gbWFrZSBhDQpkZWNpc2lvbiBvbiBob3cgdG8gYXNzaWduIHlvdXIgY2F0ZWdvcmljYWwgdmFyaWFibGVzDQoNCmBgYHtyfQ0KI01vbnRobHkNCiMgUmVzaGFwZSB0aGUgZGF0YSB0byBhIGxvbmcgZm9ybWF0DQpkZl9zYWxlc19tX2xvbmcgPC0gZGZfbWVyZ2VkX20gJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhiYXJfbSwgZm9vZF9tKSwgbmFtZXNfdG8gPSAiQ2F0ZWdvcnkiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKQ0KDQojIENyZWF0ZSB0aGUgc3RhY2tlZCBiYXIgcGxvdA0KZ2dwbG90KGRmX3NhbGVzX21fbG9uZywgYWVzKHggPSBtb250aCwgeSA9IFZhbHVlLCBmaWxsID0gQ2F0ZWdvcnkpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJzdGFjayIpICsNCiAgZ2d0aXRsZSgiTW9udGhseSBTYWxlcyBvZiBSZXN0YXVyYW50IikgKw0KICBsYWJzKHkgPSAiU2FsZXMiLCB4ID0gIk1vbnRoIiwgZmlsbCA9ICJDYXRlZ29yeSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KYGBge3J9DQojIFdlZWtseQ0KIyBSZXNoYXBlIHRoZSBkYXRhIHRvIGEgbG9uZyBmb3JtYXQNCmRmX3NhbGVzX3dfbG9uZyA8LSBkZl9tZXJnZWQNCmBgYA0KDQoNCg0KYGBge3J9DQpkZl9zYWxlc193X2xvbmcgPC0gZGZfbWVyZ2VkX3cgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhiYXJfdywgZm9vZF93KSwgbmFtZXNfdG8gPSAiQ2F0ZWdvcnkiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKQ0KDQojIENyZWF0ZSB0aGUgc3RhY2tlZCBiYXIgcGxvdA0KZ2dwbG90KGRmX3NhbGVzX3dfbG9uZywgYWVzKHggPSB3ZWVrLCB5ID0gVmFsdWUsIGZpbGwgPSBDYXRlZ29yeSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gInN0YWNrIikgKw0KICBnZ3RpdGxlKCJXZWVrbHkgU2FsZXMgb2YgUmVzdGF1cmFudCIpICsNCiAgbGFicyh5ID0gIlNhbGVzIiwgeCA9ICJXZWVrIiwgZmlsbCA9ICJDYXRlZ29yeSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBTZWFzb25hbCBwbG90cw0KDQpgYGB7cn0NCiMgU2Vhc29uYWwgcGxvdHMNCmRmX3NhbGVzX3dfZmlsdGVyZWQgPC0gZGZfbWVyZ2VkX3cgJT4lDQogIGZpbHRlcih3ZWVrID49IHltZCgiMjAyMS0xMi0zMSIpKQ0KDQoNCnRzZXJpZXNfdyA8LSB0cyhkZl9zYWxlc193X2ZpbHRlcmVkJHNhbGVzX3cgLCBzdGFydCA9IGMoMjAyMiwgMSksIGZyZXF1ZW5jeSA9IDUyKQ0KaGVhZCh0c2VyaWVzX3cpDQpzZWFzb25wbG90KHRzZXJpZXNfdywgY29sID0gcmFpbmJvdygzKSwgeWVhci5sYWJlbHMgPSBUUlVFLCBtYWluID0gIlNlYXNvbmFsIFBsb3QiKQ0KdGV4dCh4ID0gMSwgeSA9IG1heCh0c2VyaWVzX3cpIC0gMS41ZTcsIGxhYmVscyA9ICIyMDI0IiwgY29sID0gImJsdWUiKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgc2Vhc29ucGxvdCBtb250aGx5DQpkZl9zYWxlc19tX2ZpbHRlcmVkIDwtIGRmX21lcmdlZF9tICU+JQ0KICBmaWx0ZXIobW9udGggPj0geW1kKCIyMDIxLTEyLTMxIikpDQoNCg0KdHNlcmllc19tIDwtIHRzKGRmX3NhbGVzX21fZmlsdGVyZWQkc2FsZXNfbSAsIHN0YXJ0ID0gYygyMDIyLCAxKSwgZnJlcXVlbmN5ID0gMTIpDQpoZWFkKHRzZXJpZXNfbSkNCnNlYXNvbnBsb3QodHNlcmllc19tLCBjb2wgPSByYWluYm93KDMpLCB5ZWFyLmxhYmVscyA9IFRSVUUsIG1haW4gPSAiU2Vhc29uYWwgUGxvdCIpDQp0ZXh0KHggPSAxLCB5ID0gbWF4KHRzZXJpZXNfbSkgLSAxZTYsIGxhYmVscyA9ICIyMDI0IiwgY29sID0gImJsdWUiKQ0KDQpgYGANCiMjIERlbnNpdHkNCmBgYHtyfQ0KIyBNb250bHkgRGVuc2l0eQ0KIyBTZWxlY3QgdGhlIGNvbHVtbnMgb2YgaW50ZXJlc3QNCnZhcmlhYmxlcyA8LSBjKCJzYWxlc19tIiwgImJhcl9tIiwgImZvb2RfbSIsICJyYWluX20iLCAiZnhfbSIsICJnb29nbGVfbSIsDQogICAgICAgICAgICAgICAiaXNlIiwgImluZmxhdGlvbiIsICJ1bmVtcGxveW1lbnQiLCAidGVtcF9tIiwgInByY3BfbSIpDQoNCg0KIyBUcmFuc2Zvcm0gdGhlIGRhdGEgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDINCmRmX2xvbmdfbSA8LSBkZl9tZXJnZWRfbSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBhbGxfb2YodmFyaWFibGVzKSwgbmFtZXNfdG8gPSAiVmFyaWFibGUiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKQ0KDQojIENyZWF0ZSB0aGUgZ3JpZCBvZiBkZW5zaXR5IHBsb3RzDQpnZ3Bsb3QoZGZfbG9uZ19tLCBhZXMoeCA9IFZhbHVlKSkgKw0KICBnZW9tX2RlbnNpdHkoZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjQpICsNCiAgZmFjZXRfd3JhcCh+IFZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzKSArDQogIGxhYnModGl0bGUgPSAiRGVuc2l0eSBQbG90cyBvZiBTZWxlY3RlZCBWYXJpYWJsZXMiLA0KICAgICAgIHggPSAiVmFsdWUiLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KYGBge3J9DQojIFdlZWtseSBEZW5zaXR5DQojIFNlbGVjdCB0aGUgY29sdW1ucyBvZiBpbnRlcmVzdA0KdmFyaWFibGVzIDwtIGMoInNhbGVzX3ciLCAiYmFyX3ciLCAiZm9vZF93IiwgInJhaW5fdyIsICJmeF93IiwgImdvb2dsZV93IiwNCiAgICAgICAgICAgICAgICAidGVtcF93IiwgInByY3BfdyIpDQoNCg0KDQpkZl9sb25nX3cgPC0gZGZfbWVyZ2VkX3cgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYWxsX29mKHZhcmlhYmxlcyksIG5hbWVzX3RvID0gIlZhcmlhYmxlIiwgdmFsdWVzX3RvID0gIlZhbHVlIikNCg0KIyBDcmVhdGUgdGhlIGdyaWQgb2YgZGVuc2l0eSBwbG90cw0KZ2dwbG90KGRmX2xvbmdfdywgYWVzKHggPSBWYWx1ZSkpICsNCiAgZ2VvbV9kZW5zaXR5KGZpbGwgPSAiYmx1ZSIsIGFscGhhID0gMC40KSArDQogIGZhY2V0X3dyYXAofiBWYXJpYWJsZSwgc2NhbGVzID0gImZyZWUiLCBuY29sID0gMykgKw0KICBsYWJzKHRpdGxlID0gIkRlbnNpdHkgUGxvdHMgb2YgU2VsZWN0ZWQgVmFyaWFibGVzIiwNCiAgICAgICB4ID0gIlZhbHVlIiwgeSA9ICJEZW5zaXR5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCg0KYGBge3J9DQojIERhaWx5IERlbnNpdHkNCg0KIyBTZWxlY3QgdGhlIGNvbHVtbnMgb2YgaW50ZXJlc3QNCnZhcmlhYmxlcyA8LSBjKCJzYWxlc19jb3AiLCAiYmFyIiwgImZvb2QiLCAicmFpbl9zdW0iLCAiZngiLCANCiAgICAgICAgICAgICAgICJ0bWVkaWFuIiwgInByY3AiKQ0KDQoNCg0KZGZfbG9uZ19kIDwtIGRmX21lcmdlZF9kICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGFsbF9vZih2YXJpYWJsZXMpLCBuYW1lc190byA9ICJWYXJpYWJsZSIsIHZhbHVlc190byA9ICJWYWx1ZSIpDQoNCiMgQ3JlYXRlIHRoZSBncmlkIG9mIGRlbnNpdHkgcGxvdHMNCmdncGxvdChkZl9sb25nX2QsIGFlcyh4ID0gVmFsdWUpKSArDQogIGdlb21fZGVuc2l0eShmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuNCkgKw0KICBmYWNldF93cmFwKH4gVmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIiwgbmNvbCA9IDMpICsNCiAgbGFicyh0aXRsZSA9ICJEZW5zaXR5IFBsb3RzIG9mIFNlbGVjdGVkIFZhcmlhYmxlcyIsDQogICAgICAgeCA9ICJWYWx1ZSIsIHkgPSAiRGVuc2l0eSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIyBDb3ZhcmlhdGVzDQoNCmBgYHtyfQ0KIyMjIDMuNS4xIGVjb25vbWljIHZhcmlhYmxlcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGVjb25vbWljIGdyb3d0aA0KZ2dwbG90KGRmX21lcmdlZF9tLCBhZXMoeD1tb250aCwgeT1pc2UpKSArDQogIGdlb21fbGluZSgpICsgZ2d0aXRsZSgiTW9udGhseSBhY3Rpdml0eSBpbiBDb2xvbWJpYSIpDQojIGNsZWFybHkgc2Vhc29uYWwgYW5kIHRyZW5kDQoNCiMgZngNCmdncGxvdChkZl9tZXJnZWRfZCwgYWVzKHg9ZGF0ZSwgeT1meCkpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJEYWlseSBDT1AvVVNEIikNCiMgdHJlbmQgYnV0IG5vIGNsZWFyIHNlYXNvbmFsaXR5DQoNCiMgaW5mbGF0aW9uDQpnZ3Bsb3QoZGZfbWVyZ2VkX20sIGFlcyh4PW1vbnRoLCB5PWluZmxhdGlvbikpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJNb250aGx5IGluZmxhdGlvbiBOYXRpb25hbCIpDQojIGJ1c2luZXNzIGN5Y2xlcywgbm8gdGVuZCBvciBzZWFzb25hbGl0eQ0KDQojIHVuZW1wbG95bWVudA0KZ2dwbG90KGRmX21lcmdlZF9tLCBhZXMoeD1tb250aCwgeT11bmVtcGxveW1lbnQpKSArDQogIGdlb21fbGluZSgpICsgZ2d0aXRsZSgiTW9udGx5IHRyYWlsaW5nIHVuZW1wbG95bWVudCBNZWRlbGxpbiIpDQojIHNlYXNvbmFsIGFuZCB0cmVuZCBkb3dud2FyZHMNCg0KDQojIyMgMy41LjIgT3RoZXIgdmFyaWFibGVzDQoNCiMgZ29vZ2xlIHRyZW5kcw0KZ2dwbG90KGRmX21lcmdlZF93LCBhZXMoeD13ZWVrLCB5PWdvb2dsZV93KSkgKw0KICBnZW9tX2xpbmUoKSArIGdndGl0bGUoIldlZWxrbHkgR29vZ2xlIHRyZW5kcyAnUmVzdGF1cmFudGVzJyIpDQojIG5vIGNsZWFyIGJlaGF2aW91ciwgZHJvcCBpbiBwYW5kZW1pYw0KDQojIHJhaW4NCmdncGxvdChkZl9tZXJnZWRfZCwgYWVzKHg9ZGF0ZSwgeT1yYWluX3N1bSkpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJEYWlseSByYWluIGFwcHJveGltYXRlZCBpbiBBbnRpb3F1aWEiKQ0KIyBubyB0cmVuZCBvciBzZWFzb25hbGl0eSBjbGVhcmx5DQoNCiMgdGVtcGVyYXR1cmUNCmdncGxvdChkZl9tZXJnZWRfZCwgYWVzKHg9ZGF0ZSwgeT10bWVkaWFuKSkgKw0KICBnZW9tX2xpbmUoKSArIGdndGl0bGUoIkRhaWx5IE1lZGlhbiB0ZW1wZXJhdHVyZSBpbiBNZWRlbGxpbiIpDQoNCiMgYWxtb3N0IHN0YXRpb25hcnkNCg0KIyB0ZW1wZXJhdHVyZQ0KZ2dwbG90KGRmX21lcmdlZF9kLCBhZXMoeD1kYXRlLCB5PXRhdmcpKSArDQogIGdlb21fbGluZSgpICsgZ2d0aXRsZSgiRGFpbHkgQXZlcmFnZSB0ZW1wZXJhdHVyZSBpbiBNZWRlbGxpbiIpDQoNCg0KIyB0aGlzIG9uZSBsb29rcyB3ZWlyZCwgYmV0dGVyIGtlZXAgd29ya2luZyBvbiBtZWRpYW4NCg0KIyBwcmVjaXBpdGF0aW9uIGZyb20gdGVtcA0KZ2dwbG90KGRmX21lcmdlZF9kLCBhZXMoeD1kYXRlLCB5PXByY3ApKSArDQogIGdlb21fbGluZSgpICsgZ2d0aXRsZSgiRGFpbHkgIHByZWNpcGl0YXRpb24gaW4gTWVkZWxsaW4iKQ0KIyBsb29rcyBkZWNlbnQNCg0KYGBgDQoNCiMjIyBQYWlycGxvdHMNCg0KYGBge3J9DQpkZl9tZXJnZWRfZCA8LSBzdWJzZXQoZGZfbWVyZ2VkX2QsIHNlbGVjdCA9IC1yZWdpb24pDQoNCiMgZGFpbHkNCmdncGFpcnMoZGZfbWVyZ2VkX2QsIA0KICAgICAgICBjb2x1bW5zID0gMjo4KQ0KIyBzYWxlcyBoYXZlIGNvcnJlbCB3aXRoIGZ4IGFuZCByYWluX3N1bQ0KIyB3ZWVrbHkNCmdncGFpcnMoZGZfbWVyZ2VkX3csIA0KICAgICAgICBjb2x1bW5zID0gMjo5KQ0KIyBzYWxlcyBoYXZlIGNvcnJlbCB3aXRoIHJhaW4sIGdvb2dsZSwgZngsIHRlbXANCiMgYmFyIGhhcyBtb3JlIGNvcnJlbCB3aXRoIHRlbXANCg0KIyBtb250bHkNCmdncGFpcnMoZGZfbWVyZ2VkX20sIA0KICAgICAgICBjb2x1bW5zID0gMjoxMikNCg0KYGBgDQoNCiMjIyBDb3JyZWxhdGlvbiBNYXRyaXgNCg0KYGBge3J9DQojIEV4Y2x1ZGUgJ2RhdGUnIGNvbHVtbg0KbnVtZXJpY19kZl9kIDwtIGRmX21lcmdlZF9kWywgc2FwcGx5KGRmX21lcmdlZF9kLCBpcy5udW1lcmljKV0NCmNvcl9tYXRyaXhfZCA8LSBjb3IobnVtZXJpY19kZl9kLCB1c2UgPSAiY29tcGxldGUub2JzIikgICMgVXNlIG9ubHkgY29tcGxldGUgcm93cw0KY29yX21hdHJpeF9kDQoNCm51bWVyaWNfZGZfdyA8LSBkZl9tZXJnZWRfd1ssIHNhcHBseShkZl9tZXJnZWRfdywgaXMubnVtZXJpYyldDQpjb3JfbWF0cml4X3cgPC0gY29yKG51bWVyaWNfZGZfdywgdXNlID0gImNvbXBsZXRlLm9icyIpICAjIFVzZSBvbmx5IGNvbXBsZXRlIHJvd3MNCmNvcl9tYXRyaXhfdw0KDQpudW1lcmljX2RmX20gPC0gZGZfbWVyZ2VkX21bLCBzYXBwbHkoZGZfbWVyZ2VkX20sIGlzLm51bWVyaWMpXQ0KY29yX21hdHJpeF9tIDwtIGNvcihudW1lcmljX2RmX20sIHVzZSA9ICJjb21wbGV0ZS5vYnMiKSAgIyBVc2Ugb25seSBjb21wbGV0ZSByb3dzDQpjb3JfbWF0cml4X20NCg0KIyBQbG90IHRoZSBDb3JyZWxhdGlvbiBNYXRyaXgNCnBhcihtZnJvdz1jKDEsMSkpDQpjb3JycGxvdChjb3JfbWF0cml4X2QsIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCB0bC5jb2wgPSAiYmxhY2siLCB0bC5zcnQgPSA0NSkNCmNvcnJwbG90KGNvcl9tYXRyaXhfdywgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIHRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1KQ0KY29ycnBsb3QoY29yX21hdHJpeF9tLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgdGwuY29sID0gImJsYWNrIiwgdGwuc3J0ID0gNDUpDQoNCmBgYA0KUmFpbiBoYXMgc3Ryb25nZXIgY29ycmVsYXRpb24gdGhhbiBwcmNwLCBzbyB3ZSBkcm9wIHByY3AgdG8gbm90IHJlcGVhdCB0aGUgc2FtZSB2YXJpYWJsZSBmcm9tIHR3byBzb3VyY2VzDQpBbHNvIHdlIGRyb3AgYXZlcmFnZSB0ZW1wZXJhdHVyZSBiZWNhdXNlIG1lZGlhbiB0ZW1wZXJhdHVyZSBzZWVtcyBtb3JlIHRydXN0d29ydGh5DQoNCmBgYHtyfQ0KIyBkcm9wIHByY3AgYmVhY3VzZSB0aGV5ICJhcmUgdGhlIHNhbWUiDQpkZl9tZXJnZWRfbSA8LSBkZl9tZXJnZWRfbSAlPiUgc2VsZWN0KC1wcmNwX20pDQpkZl9tZXJnZWRfdyA8LSBkZl9tZXJnZWRfdyAlPiUgc2VsZWN0KC1wcmNwX3cpDQpkZl9tZXJnZWRfZCA8LSBkZl9tZXJnZWRfZCAlPiUgc2VsZWN0KC1wcmNwKQ0KDQojIGRyb3AgYXZnIHRlbXANCmRmX21lcmdlZF9kIDwtIGRmX21lcmdlZF9kICU+JSBzZWxlY3QoLXRhdmcpDQpjb2xuYW1lcyhkZl9tZXJnZWRfZCkNCmBgYA0KYGBge3J9DQojIyMgZHJvcCBldmVyeXRoaW5nIG5vdCBvbiB1c2UNCm9iamVjdHNfdG9fa2VlcCA8LSBjKCJkZl9tZXJnZWRfZCIsICJkZl9tZXJnZWRfdyIsICJkZl9tZXJnZWRfbSIpDQojIFJlbW92ZSBhbGwgb2JqZWN0cyBleGNlcHQgdGhvc2Ugc3BlY2lmaWVkDQpybShsaXN0ID0gc2V0ZGlmZihscygpLCBvYmplY3RzX3RvX2tlZXApKQ0KYGBgDQoNCg0KIyMjIFZhcmlhYmxlIFRyYW5zZm9ybWF0aW9uDQoNClBPU0lYY3QgYW5kIFBPU0lYbHQgQ2xhc3Nlcw0KDQpUaW1lcyBhbmQgZGF0ZS10aW1lcyBhcmUgcmVwcmVzZW50ZWQgYnkgdGhlIFBPU0lYY3Qgb3IgdGhlIFBPU0lYbHQgY2xhc3MNCmluIFIuIFRoZSBQT1NJWGN0IGZvcm1hdCBzdG9yZXMgZGF0ZSBhbmQgdGltZSBpbiBzZWNvbmRzIHdpdGggdGhlIG51bWJlcg0Kb2Ygc2Vjb25kcyBiZWdpbm5pbmcgYXQgSmFudWFyeSAxLCAxOTcwLCBzbyBhIFBPU0lYY3QgZGF0ZS10aW1lIGlzDQplc3NlbnRpYWxseSBhbiBzaW5nbGUgdmFsdWUgb24gYSB0aW1lbGluZS4gRGF0ZS10aW1lcyBwcmlvciB0byAxOTcwLA0Kd2lsbCBiZSBuZWdhdGl2ZSBudW1iZXJzLiBUaGUgUE9TSVhsdCBjbGFzcyBzdG9yZXMgb3RoZXIgZGF0ZSBhbmQgdGltZQ0KaW5mb3JtYXRpb24gaW4gYSBsaXN0IHN1Y2ggYXMgaG91ciBvZiBkYXkgb2Ygd2VlaywgbW9udGggb2YgeWVhciwgZXRjLg0KVGhlIHN0YXJ0aW5nIHllYXIgZm9yIFBPU0lYbHQgZGF0YSBpcyAxOTAwLCBzbyAyMDIyIHdvdWxkIGJlIHN0b3JlZCBhcw0KeWVhciAxMjIuIE1vbnRocyBhbHNvIGJlZ2luIGF0IDAsIHNvIEphbnVhcnkgaXMgc3RvcmVkIGFzIG1vbnRoIDAgYW5kDQpGZWJydWFyeSBhcyBtb250aCAxLiBGb3IgYm90aCBQT1NJWCBjbGFzc2VzLCB0aGUgdGltZXpvbmUgY2FuIGJlDQpjbGFzc2lmaWVkLiBXaGlsZSBkYXRlLXRpbWVzIHN0b3JlZCBhcyBQT1NJWGN0IGFuZCBQT1NJWGx0IGxvb2sgc2ltaWxhciwNCndoZW4geW91IHVuY2xhc3MgdGhlbSB3aXRoIHRoZSB1bmNsYXNzKCkgZnVuY3Rpb24sIHlvdSBjYW4gc2VlIHRoZQ0KYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBzdG9yZWQgd2l0aGluIHRoZSBQT1NJWGx0IGRhdGEuDQoNCkRhdGUgQ2xhc3MNCg0KRGF0ZXMgd2l0aG91dCB0aW1lIGNhbiBzaW1wbHkgYmUgc3RvcmVkIGFzIGEgRGF0ZSBjbGFzcyBpbiBSIHVzaW5nIHRoZQ0KYXMuRGF0ZSgpIGZ1bmN0aW9uLiBCb3RoIERhdGVzIGFuZCBQT1hJQyBjbGFzc2VzIG5lZWQgdG8gYmUgZGVmaW5lZA0KYmFzZWQgb24gaG93IHRoZXkgZm9ybWF0dGVkLiBXaGVuIHVwbG9hZGluZyB0aW1lIHNlcmllcyBkYXRhIGludG8gUiwNCmRhdGUgYW5kIGRhdGUtdGltZSBkYXRhIGlzIHR5cGljYWxseSB1cGxvYWRlZCBhcyBhIGNoYXJhY3RlciBjbGFzcyBhbmQNCm11c3QgYmUgY29udmVydGVkIHRvIGRhdGUgb3IgdGltZSBjbGFzcyB1c2luZyB0aGUgYXMuRGF0ZSgpLA0KYXMuUE9TSVhjdCgpIG9yIGFzLlBPU0lYbHQoKSBmdW5jdGlvbnMuDQoNCk1vbnRobHkNCg0KYGBge3J9DQojIFZhcnMgZm9yIG1vZGVsDQojIE1vbnRoDQojIEVuc3VyZSB0aGUgYG1vbnRoYCBjb2x1bW4gaXMgaW4gUE9TSVhjdCBmb3JtYXQNCmRmX21lcmdlZF9tJG1vbnRoIDwtIGFzLlBPU0lYY3QoZGZfbWVyZ2VkX20kbW9udGgpDQoNCiMgQ3JlYXRlIHRoZSBudW1lcmljIHZhcmlhYmxlOiBhbiBldmVubHkgaW5jcmVhc2luZyBudW1iZXINCmRmX21lcmdlZF9tIDwtIGRmX21lcmdlZF9tICU+JQ0KICBhcnJhbmdlKG1vbnRoKSAlPiUgICMgRW5zdXJlIGRhdGEgaXMgc29ydGVkIGJ5IG1vbnRoDQogIG11dGF0ZShudW1lcmljX21vbnRoID0gcm93X251bWJlcigpKSAgIyBBc3NpZ24gYW4gaW5jcmVhc2luZyBudW1iZXINCg0KIyBDcmVhdGUgdGhlIHNlYXNvbmFsIHZhcmlhYmxlOiB0aGUgMTIgZGlmZmVyZW50IG1vbnRocyBhcyBhIGZhY3Rvcg0KZGZfbWVyZ2VkX20gPC0gZGZfbWVyZ2VkX20gJT4lDQogIG11dGF0ZShzZWFzb25hbF9tb250aCA9IGZhY3Rvcihmb3JtYXQobW9udGgsICIlQiIpLCBsZXZlbHMgPSBtb250aC5uYW1lKSkgICMgTW9udGggbmFtZXMgYXMgb3JkZXJlZCBmYWN0b3JzDQpgYGANCg0KV2Vla2x5DQoNCmBgYHtyfQ0KIyBXZWVrDQojIEVuc3VyZSB0aGUgYHdlZWtgIGNvbHVtbiBpcyBpbiBQT1NJWGN0IGZvcm1hdA0KZGZfbWVyZ2VkX3ckd2VlayA8LSBhcy5QT1NJWGN0KGRmX21lcmdlZF93JHdlZWspDQoNCiMgQ3JlYXRlIHRoZSBudW1lcmljIHZhcmlhYmxlOiBhbiBldmVubHkgaW5jcmVhc2luZyBudW1iZXINCmRmX21lcmdlZF93IDwtIGRmX21lcmdlZF93ICU+JQ0KICBhcnJhbmdlKHdlZWspICU+JSAgIyBFbnN1cmUgZGF0YSBpcyBzb3J0ZWQgYnkgd2Vlaw0KICBtdXRhdGUobnVtZXJpY193ZWVrID0gcm93X251bWJlcigpKSAgIyBBc3NpZ24gYW4gaW5jcmVhc2luZyBudW1iZXINCg0KIyBDcmVhdGUgdGhlIHNlYXNvbmFsIHZhcmlhYmxlOiB0aGUgMTIgZGlmZmVyZW50IG1vbnRocyBhcyBhIGZhY3Rvcg0KZGZfbWVyZ2VkX3cgPC0gZGZfbWVyZ2VkX3cgJT4lDQogIG11dGF0ZShzZWFzb25hbF9tb250aCA9IGZhY3Rvcihmb3JtYXQod2VlaywgIiVCIiksIGxldmVscyA9IG1vbnRoLm5hbWUpKSAgIyBNb250aCBuYW1lcyBhcyBvcmRlcmVkIGZhY3RvcnMNCmBgYA0KDQpEYWlseQ0KDQpgYGB7cn0NCiMgRGF5DQojIEVuc3VyZSB0aGUgYGRheWAgY29sdW1uIGlzIGluIFBPU0lYY3QgZm9ybWF0DQpkZl9tZXJnZWRfZCRkYXRlIDwtIGFzLlBPU0lYY3QoZGZfbWVyZ2VkX2QkZGF0ZSkNCg0KIyBDcmVhdGUgdGhlIG51bWVyaWMgdmFyaWFibGU6IGFuIGV2ZW5seSBpbmNyZWFzaW5nIG51bWJlcg0KZGZfbWVyZ2VkX2QgPC0gZGZfbWVyZ2VkX2QgJT4lDQogIGFycmFuZ2UoZGF0ZSkgJT4lICAjIEVuc3VyZSBkYXRhIGlzIHNvcnRlZCBieSBkYXkNCiAgbXV0YXRlKG51bWVyaWNfZGF5ID0gcm93X251bWJlcigpKSAgIyBBc3NpZ24gYW4gaW5jcmVhc2luZyBudW1iZXINCmBgYA0KDQpgYGB7cn0NCiMgQ3JlYXRlIHRoZSBzZWFzb25hbCB2YXJpYWJsZTogdGhlIDEyIGRpZmZlcmVudCBtb250aHMgYXMgYSBmYWN0b3INCmRmX21lcmdlZF9kIDwtIGRmX21lcmdlZF9kICU+JQ0KICBtdXRhdGUoc2Vhc29uYWxfbW9udGggPSBmYWN0b3IoZm9ybWF0KGRhdGUsICIlQiIpLCBsZXZlbHMgPSBtb250aC5uYW1lKSkgICMgTW9udGggbmFtZXMgYXMgb3JkZXJlZCBmYWN0b3JzDQoNCiMgQ3JlYXRlIGEgY29sdW1uIGluZGljYXRpbmcgdGhlIGRheSBvZiB0aGUgd2Vlaw0KZGZfbWVyZ2VkX2QgPC0gZGZfbWVyZ2VkX2QgJT4lDQogIG11dGF0ZShkYXlfb2Zfd2VlayA9IGZhY3Rvcih3ZWVrZGF5cyhkYXRlKSwgbGV2ZWxzID0gYygiTW9uZGF5IiwgIlR1ZXNkYXkiLCAiV2VkbmVzZGF5IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGh1cnNkYXkiLCAiRnJpZGF5IiwgIlNhdHVyZGF5IiwgIlN1bmRheSIpKSkgICMgRGF5IG9mIHRoZSB3ZWVrIGFzIG9yZGVyZWQgZmFjdG9yDQpgYGANCg0KIyMjIFRpbWUgU2VyaWVzIE9iamVjdHMNCkNvbnZlcnQgc2FsZXMgdG8gdGltZSBzZXJpZXMgb2JqZWN0cyBmb3IgdGhlIHVzZSBpbiBzZXZlcmFsIG1vZGVscw0KDQpgYGB7cn0NCiMgY29udmVydCB0byB0aW1lIHNlcmllcw0Kc2FsZXNfZF90cyA8LSB0cyhkZl9tZXJnZWRfZCRzYWxlc19jb3ApDQpzYWxlc193X3RzIDwtIHRzKGRmX21lcmdlZF93JHNhbGVzX3cpDQpzYWxlc19tX3RzIDwtIHRzKGRmX21lcmdlZF9tJHNhbGVzX20pDQoNCnBhcihtZnJvdz1jKDEsMSkpDQoNCiMgRGFpbHkNCnRzZGlzcGxheShzYWxlc19kX3RzKQ0KIyBpcyBub3Qgc3RhdGlvbmFyeSBidXQgaGFzIG5vIGNsZWFyIHRyZW5kDQojIGFuZCBzZWFzb25hbGl0eSBldmVyeSA3IGRheXMNCg0KIyBXZWVrbHkNCnRzZGlzcGxheShzYWxlc193X3RzKQ0KIyBub3Qgc3RhdGlvbmFyeTogaGFzIHRyZW5kDQoNCiMgTW9udGx5DQp0c2Rpc3BsYXkoc2FsZXNfbV90cykNCiMgaGFzIGNsZWFyIHRyZW5kLCBubyBzZWFzb25hbGl0eQ0KDQpgYGANCg0KIyMjIExvZyBUcmFuc2Zvcm1hdGlvbg0KU29tZSB2YXJpYWJsZXMgYXJlIHNjYWxlZCB0byBsb2csIHNvIHdlIGNhbiBpbnRlcnByZXQgdGhlIGxpbmVhciBtb2RlbHMgbW9yZSBlYXNpbHkuIFRoZSBjb3ZhcmlhdGVzIGFyZSBpbiBkaWZmZXJlbnQgc2NhbGVzIHNvIGl0IGlzIGVhc2llciB0byBpbnRlcnByZXQgcGVyY2VudGFnZSBjaGFuZ2VzIGluc3RlYWQgb2YgdW5pdCBjaGFuZ2VzLg0KDQpgYGB7cn0NCiMgTW9udGhseQ0KZGZfbWVyZ2VkX20gPC0gZGZfbWVyZ2VkX20gJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYykgJiAhYWxsX29mKGMoInVuZW1wbG95bWVudCIsICJpbmZsYXRpb24iKSksIH4gbG9nKC4gKyAxKSkpDQoNCiMgV2Vla2x5DQpkZl9tZXJnZWRfdyA8LSBkZl9tZXJnZWRfdyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBsb2coLiArIDEpKSkNCg0KIyBEYWlseQ0KIyBXZWVrbHkNCmRmX21lcmdlZF9kIDwtIGRmX21lcmdlZF9kICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IGxvZyguICsgMSkpKQ0KDQpgYGANCg0KIyMjIEF1dG9jb3JyZWxhdGlvbg0KDQpgYGB7cn0NCiNwYXIobWZyb3c9YygxLDEpKQ0KI3RzZGlzcGxheShzYWxlc19kX3RzKQ0KIyBpcyBub3Qgc3RhdGlvbmFyeSBidXQgaGFzIG5vIGNsZWFyIHRyZW5kDQoNCnBsb3Qoc2FsZXNfZF90cykNCmFjZihzYWxlc19kX3RzKQ0KcGFjZihzYWxlc19kX3RzKQ0KYGBgDQoNCldoZW4gZGF0YSBhcmUgc2Vhc29uYWwsIHRoZSBhdXRvY29ycmVsYXRpb24gd2lsbCBiZSBsYXJnZXIgZm9yIHRoZQ0Kc2Vhc29uYWwgbGFncyAoYXQgbXVsdGlwbGVzIG9mIHRoZSBzZWFzb25hbCBwZXJpb2QpIHRoYW4gZm9yIG90aGVyIGxhZ3MuDQoNCmBgYHtyfQ0KIyBXZWVrbHkNCg0KI3RzZGlzcGxheShzYWxlc193X3RzKQ0KcGxvdChzYWxlc193X3RzKQ0KYWNmKHNhbGVzX3dfdHMpDQpwYWNmKHNhbGVzX3dfdHMpDQoNCiMgbm90IHN0YXRpb25hcnk6IGhhcyB0cmVuZCBhbmQgc2Vhc29uYWxpdHkgbWF5YmUNCmBgYA0KDQpgYGB7cn0NCiMgTW9udGx5DQoNCiN0c2Rpc3BsYXkoc2FsZXNfbV90cykNCnBsb3Qoc2FsZXNfbV90cykNCmFjZihzYWxlc19tX3RzKQ0KcGFjZihzYWxlc19tX3RzKQ0KIyBoYXMgY2xlYXIgdHJlbmQsIG5vIHNlYXNvbmFsaXR5DQpgYGANCg0KDQojIE1vZGVscw0KSW4gdGhpcyBzZWN0aW9uIHdlIG1vZGVsIHRoZSB0aW1lIHNlcmllcyB1c2luZyB2YXJpb3VzIGFwcHJvYWNoZXMgdG8gZmluZCB0aGUgYmVzdCBtb2RlbCBmb3Igb3VyIGRhdGEuDQpXZSB1c2UgYm90aCBsaW5lYXIgYW5kIG5vbiBsaW5lYXIgbW9kZWxzIGdvaW5nIGZyb20gdGhlIHNpbXBsZXN0IHRvIHRoZSBtb3JlICJjb21wbGV4IiBtb2RlbHMuDQoNCg0KIyMgSGVscGVyIGZ1bmN0aW9ucw0KRnVuY3Rpb25zIHRoYXQgaGVscCB1cyBpbXBsZW1lbnQgYW5kIGFuYWx5emUgbW9kZWxzIGZhc3Rlcg0KYGBge3J9DQojIyBGdW5jdGlvbiB0byBjcmVhdGUgYW5kIHN1bW1hcml6ZSBtb2RlbHMtLS0tLS0tLS0tLS0tLS0tLS0NCnJ1bl9tb2RlbCA8LSBmdW5jdGlvbihmb3JtdWxhLCBkYXRhLCBtb2RlbF9uYW1lKSB7DQogIGNhdCgiXG5SdW5uaW5nIiwgbW9kZWxfbmFtZSwgIlxuIikNCiAgbW9kZWwgPC0gbG0oZm9ybXVsYSwgZGF0YSA9IGRhdGEpDQogIHByaW50KHN1bW1hcnkobW9kZWwpKQ0KICBwYXIobWZyb3cgPSBjKDIsIDIpKQ0KICBwbG90KG1vZGVsKQ0KICByZXR1cm4obW9kZWwpDQp9DQoNCiMgRnVuY3Rpb24gdG8gY29tcGFyZSBtb2RlbHMgdXNpbmcgQU5PVkENCmNvbXBhcmVfbW9kZWxzIDwtIGZ1bmN0aW9uKG1vZGVsMSwgbW9kZWwyLCBuYW1lMSwgbmFtZTIpIHsNCiAgY2F0KCJcbkNvbXBhcmluZyBNb2RlbHM6IiwgbmFtZTEsICJ2cyIsIG5hbWUyLCAiXG4iKQ0KICBhbm92YV9yZXN1bHQgPC0gYW5vdmEobW9kZWwxLCBtb2RlbDIpDQogIHByaW50KGFub3ZhX3Jlc3VsdCkNCiAgcmV0dXJuKGFub3ZhX3Jlc3VsdCkNCn0NCg0KIyBGdW5jdGlvbiB0byBhZGQgcHJlZGljdGlvbnMgdG8gdGhlIGRhdGFzZXQNCmFkZF9wcmVkaWN0aW9ucyA8LSBmdW5jdGlvbihtb2RlbCwgZGF0YSwgcHJlZF9jb2x1bW4pIHsNCiAgZGF0YVtbcHJlZF9jb2x1bW5dXSA8LSBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhID0gZGF0YSkNCiAgcmV0dXJuKGRhdGEpDQp9DQoNCiMgQ2FsY3VsYXRlIFJNU0UNCiMgRnVuY3Rpb24gdG8gY2FsY3VsYXRlIFJNU0UNCmNhbGN1bGF0ZV9ybXNlIDwtIGZ1bmN0aW9uKG9ic2VydmVkLCBwcmVkaWN0ZWQpIHsNCiAgcm1zZSA8LSBzcXJ0KG1lYW4oKG9ic2VydmVkIC0gcHJlZGljdGVkKV4yLCBuYS5ybSA9IFRSVUUpKQ0KICByZXR1cm4ocm1zZSkNCn0NCg0KDQojIGZ1bmN0aW9uIHRoYXQgY29tcGFyZXMgbGluZWFyIG1vZGVscw0KIyBEZWZpbmUgdGhlIGZ1bmN0aW9uIHRvIGdldCBSXjIgYW5kIEFJQw0KZ2V0X21vZGVsX3N0YXRzIDwtIGZ1bmN0aW9uKG1vZGVscykgew0KICAjIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YSBmcmFtZQ0KICBzdGF0cyA8LSBkYXRhLmZyYW1lKA0KICAgIE1vZGVsID0gY2hhcmFjdGVyKCksDQogICAgUjIgPSBudW1lcmljKCksDQogICAgQUlDID0gbnVtZXJpYygpLA0KICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQ0KICApDQogIA0KICAjIExvb3AgdGhyb3VnaCB0aGUgbGlzdCBvZiBtb2RlbHMNCiAgZm9yIChpIGluIHNlcV9hbG9uZyhtb2RlbHMpKSB7DQogICAgbW9kZWwgPC0gbW9kZWxzW1tpXV0NCiAgICBtb2RlbF9uYW1lIDwtIG5hbWVzKG1vZGVscylbaV0NCiAgICAjIEV4dHJhY3QgUl4yIGFuZCBBSUMNCiAgICByMiA8LSBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQNCiAgICBhaWMgPC0gQUlDKG1vZGVsKQ0KICAgICMgQXBwZW5kIHRvIHRoZSBkYXRhIGZyYW1lDQogICAgc3RhdHMgPC0gcmJpbmQoc3RhdHMsIGRhdGEuZnJhbWUoTW9kZWwgPSBtb2RlbF9uYW1lLCBSMiA9IHIyLCBBSUMgPSBhaWMpKQ0KICB9DQogIA0KICByZXR1cm4oc3RhdHMpDQp9DQoNCmBgYA0KDQoNCiMjIExpbmVhciBtb2RlbHMNCg0KYGBge3J9DQojIE1vbnRseSBNb2RlbHMNCiMgVmlldyBEYXRhZnJhbWUNCmhlYWQoZGZfbWVyZ2VkX20pDQoNCiMgTW9kZWwgMDogVHJlbmQgb25seQ0Kb2xzMCA8LSBydW5fbW9kZWwoc2FsZXNfbSB+IG51bWVyaWNfbW9udGgsIGRmX21lcmdlZF9tLCAiTW9kZWwgMCIpDQpkZl9tZXJnZWRfbSA8LSBhZGRfcHJlZGljdGlvbnMob2xzMCwgZGZfbWVyZ2VkX20sICJwcmVkaWN0ZWRfc2FsZXMwIikNCg0KIyBNb2RlbCAxOiBUcmVuZCArIFNlYXNvbmFsaXR5DQpvbHMxIDwtIHJ1bl9tb2RlbChzYWxlc19tIH4gbnVtZXJpY19tb250aCArIHNlYXNvbmFsX21vbnRoLCBkZl9tZXJnZWRfbSwgIk1vZGVsIDEiKQ0KZGZfbWVyZ2VkX20gPC0gYWRkX3ByZWRpY3Rpb25zKG9sczEsIGRmX21lcmdlZF9tLCAicHJlZGljdGVkX3NhbGVzMSIpDQoNCg0KIyMgTW9kZWwgMjogQmFja3dhcmQgU3RlcHdpc2UgUmVncmVzc2lvbiANCg0KIyBTdGFydCB3aXRoIHRoZSBmdWxsIG1vZGVsIChleGNsdWRpbmcgZm9vZCBhbmQgYmFyKQ0Kb2xzMl9mdWxsIDwtIGxtKA0KICBzYWxlc19tIH4gbnVtZXJpY19tb250aCArIHNlYXNvbmFsX21vbnRoICsgdW5lbXBsb3ltZW50ICsgaXNlICsgZnhfbSArDQogICAgZ29vZ2xlX20gKyB0ZW1wX20gKyByYWluX20sIA0KICBkYXRhID0gZGZfbWVyZ2VkX20NCikNCg0KDQojIFBlcmZvcm0gYmFja3dhcmQgc3RlcHdpc2UgcmVncmVzc2lvbg0Kb2xzMl9zdGVwd2lzZSA8LSBzdGVwKA0KICBvbHMyX2Z1bGwsIA0KICBkaXJlY3Rpb24gPSAiYmFja3dhcmQiLA0KICB0cmFjZSA9IDEgIyBQcmludHMgdGhlIHN0ZXB3aXNlIHJlZ3Jlc3Npb24gcHJvY2Vzcw0KKQ0KDQojIFN1bW1hcnkgb2YgdGhlIGZpbmFsIHN0ZXB3aXNlIG1vZGVsDQpzdW1tYXJ5KG9sczJfc3RlcHdpc2UpDQoNCiMgQWRkIHByZWRpY3Rpb25zIGZyb20gdGhlIGZpbmFsIHN0ZXB3aXNlIG1vZGVsDQpkZl9tZXJnZWRfbSA8LSBhZGRfcHJlZGljdGlvbnMob2xzMl9zdGVwd2lzZSwgZGZfbWVyZ2VkX20sICJwcmVkaWN0ZWRfc2FsZXMyIikNCg0KIyBQbG90IEFjdHVhbCB2cyBQcmVkaWN0ZWQgVmFsdWVzDQpnZ3Bsb3QoZGZfbWVyZ2VkX20sIGFlcyh4ID0gbW9udGgpKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV4cChzYWxlc19tKSwgY29sb3IgPSAiQWN0dWFsIFNhbGVzIiksIHNpemUgPSAxKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV4cChwcmVkaWN0ZWRfc2FsZXMwKSwgY29sb3IgPSAiTW9kZWwgMCIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHAocHJlZGljdGVkX3NhbGVzMSksIGNvbG9yID0gIk1vZGVsIDEiKSwgbGluZXR5cGUgPSAiZG90dGVkIiwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gZXhwKHByZWRpY3RlZF9zYWxlczIpLCBjb2xvciA9ICJNb2RlbCAyIFN0ZXB3aXNlIiksIGxpbmV0eXBlID0gImRvdGRhc2giLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIkFjdHVhbCB2cyBQcmVkaWN0ZWQgTW9udGhseSBTYWxlcyBmb3IgQWxsIE1vZGVscyIsDQogICAgICAgeCA9ICJNb250aCIsIHkgPSAiU2FsZXMiLCBjb2xvciA9ICJMZWdlbmQiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCg0KIyBNb2RlbHMgdG8gY29tcGFyZQ0KbW9kZWxzIDwtIGxpc3QoDQogICJNb2RlbCB0cmVuZCIgPSBvbHMwLA0KICAiTW9kZWwgdHJlbmQgKyBzZWFzb24iID0gb2xzMSwNCiAgIk1vZGVsIGFsbCBjb3ZhcmlhdGVzIHN0ZXAiID0gb2xzMl9zdGVwd2lzZQ0KKQ0KDQojIEdldCBSXjIgYW5kIEFJQyBmb3IgZWFjaCBtb2RlbA0KbW9kZWxfc3RhdHMgPC0gZ2V0X21vZGVsX3N0YXRzKG1vZGVscykNCg0KIyBWaWV3IHRoZSByZXN1bHRzDQpwcmludChtb2RlbF9zdGF0cykNCg0KDQojICBSTVNFIGNhbGN1bGF0aW9uIGZvciB0aGUgb3JpZ2luYWwgKGV4cG9uZW50aWF0ZWQpIHNjYWxlDQpybXNlX3N0YXRzIDwtIGRhdGEuZnJhbWUoDQogIE1vZGVsID0gY2hhcmFjdGVyKCksDQogIFJNU0UgPSBudW1lcmljKCksDQogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQ0KKQ0KDQojIExvb3AgdGhyb3VnaCBlYWNoIG1vZGVsDQpmb3IgKGkgaW4gc2VxX2Fsb25nKG1vZGVscykpIHsNCiAgbW9kZWxfbmFtZSA8LSBuYW1lcyhtb2RlbHMpW2ldDQogIHByZWRpY3RlZF9jb2x1bW4gPC0gcGFzdGUwKCJwcmVkaWN0ZWRfc2FsZXMiLCBpIC0gMSkgICMgQWRqdXN0IGNvbHVtbiBuYW1lIGluZGV4DQogIA0KICAjIENhbGN1bGF0ZSBSTVNFIG9uIHRoZSBvcmlnaW5hbCBzY2FsZQ0KICBybXNlIDwtIGNhbGN1bGF0ZV9ybXNlKA0KICAgIG9ic2VydmVkID0gZXhwKGRmX21lcmdlZF9tJHNhbGVzX20pLCAgICAgICAgICAjIEV4cG9uZW50aWF0ZSBhY3R1YWwgdmFsdWVzDQogICAgcHJlZGljdGVkID0gZXhwKGRmX21lcmdlZF9tW1twcmVkaWN0ZWRfY29sdW1uXV0pICAjIEV4cG9uZW50aWF0ZSBwcmVkaWN0ZWQgdmFsdWVzDQogICkNCiAgDQogICMgQXBwZW5kIHJlc3VsdHMgdG8gdGhlIFJNU0Ugc3RhdHMgdGFibGUNCiAgcm1zZV9zdGF0cyA8LSByYmluZChybXNlX3N0YXRzLCBkYXRhLmZyYW1lKE1vZGVsID0gbW9kZWxfbmFtZSwgUk1TRSA9IHJtc2UpKQ0KfQ0KDQojIFZpZXcgUk1TRSBzdGF0aXN0aWNzDQpwcmludChybXNlX3N0YXRzKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnJtc2Vfb2xzX20gPC0gcm1zZV9zdGF0cyRSTVNFWzNdDQpybXNlX29sc19tDQpgYGANCg0KYGBge3J9DQojIFdlZWtseSBNb2RlbHMNCmhlYWQoZGZfbWVyZ2VkX3cpDQojIyBDbGVhbiBEYXRhIC0gRHJvcCByb3dzIDEtMiBiZWNhdXNlIHNhbGVzIGFyZSAwIC8gd2FzIG5vdCBvcGVuIHlldA0KZGZfbWVyZ2VkX3cgPC0gZGZfbWVyZ2VkX3cgJT4lIHNsaWNlKC0xLCAtMikNCg0KIyMgTW9kZWwgMEE6IFRyZW5kIG9ubHkNCm9sczB3IDwtIHJ1bl9tb2RlbChzYWxlc193IH4gbnVtZXJpY193ZWVrLCBkZl9tZXJnZWRfdywgIk1vZGVsIDBBIikNCmRmX21lcmdlZF93IDwtIGFkZF9wcmVkaWN0aW9ucyhvbHMwdywgZGZfbWVyZ2VkX3csICJwcmVkaWN0ZWRfc2FsZXMwIikNCg0KIyMgTW9kZWwgMUE6IFRyZW5kICsgU2Vhc29uYWxpdHkNCm9sczF3IDwtIHJ1bl9tb2RlbChzYWxlc193IH4gbnVtZXJpY193ZWVrICsgc2Vhc29uYWxfbW9udGgsIGRmX21lcmdlZF93LCAiTW9kZWwgMUEiKQ0KZGZfbWVyZ2VkX3cgPC0gYWRkX3ByZWRpY3Rpb25zKG9sczF3LCBkZl9tZXJnZWRfdywgInByZWRpY3RlZF9zYWxlczEiKQ0KDQoNCiMjIE1vZGVsIDJBOiBFeHBlcmltZW50YXRpb24NCg0KDQojIFN0YXJ0IHdpdGggdGhlIGZ1bGwgbW9kZWwgKGV4Y2x1ZGluZyBmb29kIGFuZCBiYXIpDQpvbHMyX2Z1bGxfdyA8LSBsbSgNCiAgc2FsZXNfdyB+IG51bWVyaWNfd2VlayArIHNlYXNvbmFsX21vbnRoICsgZnhfdyArDQogICAgZ29vZ2xlX3cgKyB0ZW1wX3cgKyByYWluX3csIA0KICBkYXRhID0gZGZfbWVyZ2VkX3cNCikNCg0KDQojIFBlcmZvcm0gYmFja3dhcmQgc3RlcHdpc2UgcmVncmVzc2lvbg0Kb2xzMl9zdGVwd2lzZV93IDwtIHN0ZXAoDQogIG9sczJfZnVsbF93LCANCiAgZGlyZWN0aW9uID0gImJhY2t3YXJkIiwNCiAgdHJhY2UgPSAxICMgUHJpbnRzIHRoZSBzdGVwd2lzZSByZWdyZXNzaW9uIHByb2Nlc3MNCikNCg0KIyBTdW1tYXJ5IG9mIHRoZSBmaW5hbCBzdGVwd2lzZSBtb2RlbA0Kc3VtbWFyeShvbHMyX3N0ZXB3aXNlX3cpDQoNCiMgQWRkIHByZWRpY3Rpb25zIGZyb20gdGhlIGZpbmFsIHN0ZXB3aXNlIG1vZGVsDQpkZl9tZXJnZWRfdyA8LSBhZGRfcHJlZGljdGlvbnMob2xzMl9zdGVwd2lzZV93LCBkZl9tZXJnZWRfdywgInByZWRpY3RlZF9zYWxlczIiKQ0KDQojIFBsb3QgQWN0dWFsIHZzIFByZWRpY3RlZCBWYWx1ZXMNCmdncGxvdChkZl9tZXJnZWRfdywgYWVzKHggPSB3ZWVrKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHAoc2FsZXNfdyksIGNvbG9yID0gIkFjdHVhbCBTYWxlcyIpLCBzaXplID0gMSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHAocHJlZGljdGVkX3NhbGVzMCksIGNvbG9yID0gIk1vZGVsIDAiKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gZXhwKHByZWRpY3RlZF9zYWxlczEpLCBjb2xvciA9ICJNb2RlbCAxIiksIGxpbmV0eXBlID0gImRvdHRlZCIsIHNpemUgPSAxKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV4cChwcmVkaWN0ZWRfc2FsZXMyKSwgY29sb3IgPSAiTW9kZWwgMiBTdGVwd2lzZSIpLCBsaW5ldHlwZSA9ICJkb3RkYXNoIiwgc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJBY3R1YWwgdnMgUHJlZGljdGVkIFdlZWtseSBTYWxlcyBmb3IgQWxsIE1vZGVscyIsDQogICAgICAgeCA9ICJXZWVrIiwgeSA9ICJTYWxlcyIsIGNvbG9yID0gIkxlZ2VuZCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KIyBNb2RlbHMgdG8gY29tcGFyZQ0KbW9kZWxzX3cgPC0gbGlzdCgNCiAgIk1vZGVsIHRyZW5kIiA9IG9sczB3LA0KICAiTW9kZWwgdHJlbmQgKyBzZWFzb24iID0gb2xzMXcsDQogICJNb2RlbCBhbGwgY292YXJpYXRlcyBzdGVwIiA9IG9sczJfc3RlcHdpc2Vfdw0KKQ0KDQojIEdldCBSXjIgYW5kIEFJQyBmb3IgZWFjaCBtb2RlbA0KbW9kZWxfc3RhdHNfdyA8LSBnZXRfbW9kZWxfc3RhdHMobW9kZWxzX3cpDQoNCiMgVmlldyB0aGUgcmVzdWx0cw0KcHJpbnQobW9kZWxfc3RhdHNfdykNCg0KDQpybXNlX3N0YXRzX3cgPC0gZGF0YS5mcmFtZSgNCiAgTW9kZWwgPSBjaGFyYWN0ZXIoKSwNCiAgUk1TRSA9IG51bWVyaWMoKSwNCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFDQopDQoNCiMgTG9vcCB0aHJvdWdoIGVhY2ggbW9kZWwNCmZvciAoaSBpbiBzZXFfYWxvbmcobW9kZWxzX3cpKSB7DQogIG1vZGVsX25hbWUgPC0gbmFtZXMobW9kZWxzX3cpW2ldDQogIHByZWRpY3RlZF9jb2x1bW4gPC0gcGFzdGUwKCJwcmVkaWN0ZWRfc2FsZXMiLCBpIC0gMSkgICMgQWRqdXN0IGNvbHVtbiBuYW1lIGluZGV4DQogIA0KICAjIENhbGN1bGF0ZSBSTVNFIG9uIHRoZSBvcmlnaW5hbCBzY2FsZQ0KICBybXNlIDwtIGNhbGN1bGF0ZV9ybXNlKA0KICAgIG9ic2VydmVkID0gZXhwKGRmX21lcmdlZF93JHNhbGVzX3cpLCAgICAgICAgICAjIEV4cG9uZW50aWF0ZSBhY3R1YWwgdmFsdWVzDQogICAgcHJlZGljdGVkID0gZXhwKGRmX21lcmdlZF93W1twcmVkaWN0ZWRfY29sdW1uXV0pICAjIEV4cG9uZW50aWF0ZSBwcmVkaWN0ZWQgdmFsdWVzDQogICkNCiAgDQogICMgQXBwZW5kIHJlc3VsdHMgdG8gdGhlIFJNU0Ugc3RhdHMgdGFibGUNCiAgcm1zZV9zdGF0c193IDwtIHJiaW5kKHJtc2Vfc3RhdHNfdywgZGF0YS5mcmFtZShNb2RlbCA9IG1vZGVsX25hbWUsIFJNU0UgPSBybXNlKSkNCn0NCg0KIyBWaWV3IFJNU0Ugc3RhdGlzdGljcw0KcHJpbnQocm1zZV9zdGF0c193KQ0KDQpgYGANCg0KYGBge3J9DQpybXNlX29sc193IDwtIHJtc2Vfc3RhdHNfdyRSTVNFWzNdDQpybXNlX29sc193DQpgYGANCg0KDQpgYGB7cn0NCiMgRGFpbHkgTW9kZWxzDQpoZWFkKGRmX21lcmdlZF9kLDI1KQ0KIyBwcm9wZXJseSBzdGFydCBpbiBkZWNlbWJlcg0KZGZfbWVyZ2VkX2QgPC0gIGRmX21lcmdlZF9kICU+JQ0KICBmaWx0ZXIoZGF0ZSA+ICIyMDIxLTExLTMwIikNCmhlYWQoZGZfbWVyZ2VkX2QpDQoNCiMjIE1vZGVsIDA6IFRyZW5kIG9ubHkNCm9sczBkIDwtIHJ1bl9tb2RlbChzYWxlc19jb3AgfiBudW1lcmljX2RheSwgZGZfbWVyZ2VkX2QsICJNb2RlbCAwQSIpDQpkZl9tZXJnZWRfZCA8LSBhZGRfcHJlZGljdGlvbnMob2xzMGQsIGRmX21lcmdlZF9kLCAicHJlZGljdGVkX3NhbGVzMCIpDQoNCiMjIE1vZGVsIDE6IFRyZW5kICsgU2Vhc29uYWxpdHkNCm9sczFkIDwtIHJ1bl9tb2RlbChzYWxlc19jb3AgfiBudW1lcmljX2RheSArIHNlYXNvbmFsX21vbnRoICsgZGF5X29mX3dlZWssIGRmX21lcmdlZF9kLCAiTW9kZWwgMUEiKQ0KZGZfbWVyZ2VkX2QgPC0gYWRkX3ByZWRpY3Rpb25zKG9sczFkLCBkZl9tZXJnZWRfZCwgInByZWRpY3RlZF9zYWxlczEiKQ0KDQojIE1vZGVsIDI6IEJhY2t3YXJkDQpoZWFkKGRmX21lcmdlZF9kKQ0KDQojIFN0YXJ0IHdpdGggdGhlIGZ1bGwgbW9kZWwgKGV4Y2x1ZGluZyBmb29kIGFuZCBiYXIpDQpvbHMyX2Z1bGxfZCA8LSBsbSgNCiAgc2FsZXNfY29wIH4gbnVtZXJpY19kYXkgKyBzZWFzb25hbF9tb250aCArIGRheV9vZl93ZWVrICsgZnggKw0KICAgICB0bWVkaWFuICsgcmFpbl9zdW0sIA0KICBkYXRhID0gZGZfbWVyZ2VkX2QNCikNCnN1bW1hcnkob2xzMl9mdWxsX2QpDQoNCiMgUGVyZm9ybSBiYWNrd2FyZCBzdGVwd2lzZSByZWdyZXNzaW9uDQpvbHMyX3N0ZXB3aXNlX2QgPC0gc3RlcCgNCiAgb2xzMl9mdWxsX2QsIA0KICBkaXJlY3Rpb24gPSAiYmFja3dhcmQiLA0KICB0cmFjZSA9IDEgIyBQcmludHMgdGhlIHN0ZXB3aXNlIHJlZ3Jlc3Npb24gcHJvY2Vzcw0KKQ0KDQojIFN1bW1hcnkgb2YgdGhlIGZpbmFsIHN0ZXB3aXNlIG1vZGVsDQpzdW1tYXJ5KG9sczJfc3RlcHdpc2VfZCkNCg0KIyBBZGQgcHJlZGljdGlvbnMgZnJvbSB0aGUgZmluYWwgc3RlcHdpc2UgbW9kZWwNCmRmX21lcmdlZF9kIDwtIGFkZF9wcmVkaWN0aW9ucyhvbHMyX3N0ZXB3aXNlX2QsIGRmX21lcmdlZF9kLCAicHJlZGljdGVkX3NhbGVzMiIpDQoNCiMgUGxvdCBBY3R1YWwgdnMgUHJlZGljdGVkIFZhbHVlcw0KZ2dwbG90KGRmX21lcmdlZF9kLCBhZXMoeCA9IGRhdGUpKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV4cChzYWxlc19jb3ApLCBjb2xvciA9ICJBY3R1YWwgU2FsZXMiKSwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gZXhwKHByZWRpY3RlZF9zYWxlczApLCBjb2xvciA9ICJNb2RlbCAwIiksIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxKSArDQogIGdlb21fbGluZShhZXMoeSA9IGV4cChwcmVkaWN0ZWRfc2FsZXMxKSwgY29sb3IgPSAiTW9kZWwgMSIpLCBsaW5ldHlwZSA9ICJkb3R0ZWQiLCBzaXplID0gMSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHAocHJlZGljdGVkX3NhbGVzMiksIGNvbG9yID0gIk1vZGVsIDIgU3RlcHdpc2UiKSwgbGluZXR5cGUgPSAiZG90ZGFzaCIsIHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiQWN0dWFsIHZzIFByZWRpY3RlZCBTYWxlcyBmb3IgQWxsIE1vZGVscyIsDQogICAgICAgeCA9ICJkYXRlIiwgeSA9ICJTYWxlcyIsIGNvbG9yID0gIkxlZ2VuZCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KDQojIE1vZGVscyB0byBjb21wYXJlDQptb2RlbHNfZCA8LSBsaXN0KA0KICAiTW9kZWwgdHJlbmQiID0gb2xzMGQsDQogICJNb2RlbCB0cmVuZCArIHNlYXNvbiIgPSBvbHMxZCwNCiAgIk1vZGVsIGFsbCBjb3ZhcmlhdGVzIHN0ZXAiID0gb2xzMl9zdGVwd2lzZV9kDQopDQoNCiMgR2V0IFJeMiBhbmQgQUlDIGZvciBlYWNoIG1vZGVsDQptb2RlbF9zdGF0c19kIDwtIGdldF9tb2RlbF9zdGF0cyhtb2RlbHNfZCkNCg0KIyBWaWV3IHRoZSByZXN1bHRzDQpwcmludChtb2RlbF9zdGF0c19kKQ0KDQojICBSTVNFIGNhbGN1bGF0aW9uIGZvciB0aGUgb3JpZ2luYWwgKGV4cG9uZW50aWF0ZWQpIHNjYWxlIGZvciBkYWlseSBtb2RlbHMNCnJtc2Vfc3RhdHNfZCA8LSBkYXRhLmZyYW1lKA0KICBNb2RlbCA9IGNoYXJhY3RlcigpLA0KICBSTVNFID0gbnVtZXJpYygpLA0KICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UNCikNCg0KIyBMb29wIHRocm91Z2ggZWFjaCBtb2RlbA0KZm9yIChpIGluIHNlcV9hbG9uZyhtb2RlbHNfZCkpIHsNCiAgbW9kZWxfbmFtZSA8LSBuYW1lcyhtb2RlbHNfZClbaV0NCiAgcHJlZGljdGVkX2NvbHVtbiA8LSBwYXN0ZTAoInByZWRpY3RlZF9zYWxlcyIsIGkgLSAxKSAgIyBBZGp1c3QgY29sdW1uIG5hbWUgaW5kZXgNCiAgDQogICMgQ2FsY3VsYXRlIFJNU0Ugb24gdGhlIG9yaWdpbmFsIHNjYWxlDQogIHJtc2UgPC0gY2FsY3VsYXRlX3Jtc2UoDQogICAgb2JzZXJ2ZWQgPSBleHAoZGZfbWVyZ2VkX2Qkc2FsZXNfY29wKSwgICAgICAgICAgIyBFeHBvbmVudGlhdGUgYWN0dWFsIHZhbHVlcw0KICAgIHByZWRpY3RlZCA9IGV4cChkZl9tZXJnZWRfZFtbcHJlZGljdGVkX2NvbHVtbl1dKSAgIyBFeHBvbmVudGlhdGUgcHJlZGljdGVkIHZhbHVlcw0KICApDQogIA0KICAjIEFwcGVuZCByZXN1bHRzIHRvIHRoZSBSTVNFIHN0YXRzIHRhYmxlDQogIHJtc2Vfc3RhdHNfZCA8LSByYmluZChybXNlX3N0YXRzX2QsIGRhdGEuZnJhbWUoTW9kZWwgPSBtb2RlbF9uYW1lLCBSTVNFID0gcm1zZSkpDQp9DQoNCiMgVmlldyBSTVNFIHN0YXRpc3RpY3MgZm9yIGRhaWx5IGRhdGENCnByaW50KHJtc2Vfc3RhdHNfZCkNCmBgYA0KDQpgYGB7cn0NCnJtc2Vfb2xzX2QgPC0gcm1zZV9zdGF0c19kJFJNU0VbM10NCnJtc2Vfb2xzX2QNCmBgYA0KDQojIyBOb24gTGluZWFyIE1vZGVscw0KSGVyZSB3ZSBleHBsb3JlIG5vbiBsaW5lYXIgbW9kZWxzLCBzdGFydGluZyBmcm9tIHRoZSBzaW1wbGVzdCB0byBtb3JlIGVsYWJvcmF0ZSBtb2RlbHMgaW4gdGhlIGVuZCBjb21iaW5pbmcgc29tZSBvZiB0aGUgdXNlZCBtb2RlbHMuDQoNCiMjIyBXcmFuZ2xlIGRhdGEgZm9yIG1vZGVscw0KVGhlIHRpbWUgc2VyaWVzIGFyZSBhbHRlcmVkIHNvIHRoZSB2aXN1YWxpemF0aW9ucyBhcmUgbW9yZSB1bmRlcnN0YW5kYWJsZSwgYmFzaWNhbGx5IHdlIGNoYW5nZSB0aGUgZGF0ZSBpbmRleCBpbiB0aGUgdGltZXNlcmllcyBvYmplY3RzDQoNCmBgYHtyfQ0KIyByZS1kZWNsYXJlIHRpbWUtc2VyaWVzIGJlYWNhdXNlIHdlIGRyb3BlZCBzb21lIHJvd3M6DQojIEVuc3VyZSB0aGUgJ2RhdGUnIGNvbHVtbnMgYXJlIGluIERhdGUgZm9ybWF0DQpkZl9tZXJnZWRfZCRkYXRlIDwtIGFzLkRhdGUoZGZfbWVyZ2VkX2QkZGF0ZSkNCmRmX21lcmdlZF93JGRhdGUgPC0gYXMuRGF0ZShkZl9tZXJnZWRfdyR3ZWVrKQ0KZGZfbWVyZ2VkX20kZGF0ZSA8LSBhcy5EYXRlKGRmX21lcmdlZF9tJG1vbnRoKQ0KDQojIEV4dHJhY3QgdGhlIHN0YXJ0IGRhdGUgYW5kIHllYXIgZm9yIGVhY2ggZGF0YWZyYW1lDQpzdGFydF9kIDwtIG1pbihkZl9tZXJnZWRfZCRkYXRlKQ0Kc3RhcnRfdyA8LSBtaW4oZGZfbWVyZ2VkX3ckZGF0ZSkNCnN0YXJ0X20gPC0gbWluKGRmX21lcmdlZF9tJGRhdGUpDQoNCiMgRXh0cmFjdCBjb21wb25lbnRzIGZvciBkYWlseSwgd2Vla2x5LCBhbmQgbW9udGhseSBzdGFydCB0aW1lcw0Kc3RhcnRfZF95ZWFyIDwtIGFzLm51bWVyaWMoZm9ybWF0KHN0YXJ0X2QsICIlWSIpKQ0Kc3RhcnRfZF9kYXkgPC0gYXMubnVtZXJpYyhmb3JtYXQoc3RhcnRfZCwgIiVqIikpICMgRGF5IG9mIHRoZSB5ZWFyDQoNCnN0YXJ0X3dfeWVhciA8LSBhcy5udW1lcmljKGZvcm1hdChzdGFydF93LCAiJVkiKSkNCnN0YXJ0X3dfd2VlayA8LSBhcy5udW1lcmljKGZvcm1hdChzdGFydF93LCAiJVUiKSkgKyAxICMgV2VlayBudW1iZXIsIGFkZGluZyAxIHNpbmNlIFIgc3RhcnRzIGF0IHdlZWsgMA0KDQpzdGFydF9tX3llYXIgPC0gYXMubnVtZXJpYyhmb3JtYXQoc3RhcnRfbSwgIiVZIikpDQpzdGFydF9tX21vbnRoIDwtIGFzLm51bWVyaWMoZm9ybWF0KHN0YXJ0X20sICIlbSIpKQ0KDQojIERlY2xhcmUgdGltZSBzZXJpZXMgd2l0aCBhcHByb3ByaWF0ZSBmcmVxdWVuY2llcw0Kc2FsZXNfZF90cyA8LSB0cyhleHAoZGZfbWVyZ2VkX2Qkc2FsZXNfY29wKSwgc3RhcnQgPSBjKHN0YXJ0X2RfeWVhciwgc3RhcnRfZF9kYXkpLCBmcmVxdWVuY3kgPSAzNjUpDQpzYWxlc193X3RzIDwtIHRzKGV4cChkZl9tZXJnZWRfdyRzYWxlc193KSwgc3RhcnQgPSBjKHN0YXJ0X3dfeWVhciwgc3RhcnRfd193ZWVrKSwgZnJlcXVlbmN5ID0gNTIpDQpzYWxlc19tX3RzIDwtIHRzKGV4cChkZl9tZXJnZWRfbSRzYWxlc19tKSwgc3RhcnQgPSBjKHN0YXJ0X21feWVhciwgc3RhcnRfbV9tb250aCksIGZyZXF1ZW5jeSA9IDEyKQ0KDQpmb29kX2RfdHMgPC0gdHMoZXhwKGRmX21lcmdlZF9kJGZvb2QpLCBzdGFydCA9IGMoc3RhcnRfZF95ZWFyLCBzdGFydF9kX2RheSksIGZyZXF1ZW5jeSA9IDM2NSkNCmZvb2Rfd190cyA8LSB0cyhleHAoZGZfbWVyZ2VkX3ckZm9vZF93KSwgc3RhcnQgPSBjKHN0YXJ0X3dfeWVhciwgc3RhcnRfd193ZWVrKSwgZnJlcXVlbmN5ID0gNTIpDQpmb29kX21fdHMgPC0gdHMoZXhwKGRmX21lcmdlZF9tJGZvb2RfbSksIHN0YXJ0ID0gYyhzdGFydF9tX3llYXIsIHN0YXJ0X21fbW9udGgpLCBmcmVxdWVuY3kgPSAxMikNCg0KYmFyX2RfdHMgPC0gdHMoZXhwKGRmX21lcmdlZF9kJGJhciksIHN0YXJ0ID0gYyhzdGFydF9kX3llYXIsIHN0YXJ0X2RfZGF5KSwgZnJlcXVlbmN5ID0gMzY1KQ0KYmFyX3dfdHMgPC0gdHMoZXhwKGRmX21lcmdlZF93JGJhcl93KSwgc3RhcnQgPSBjKHN0YXJ0X3dfeWVhciwgc3RhcnRfd193ZWVrKSwgZnJlcXVlbmN5ID0gNTIpDQpiYXJfbV90cyA8LSB0cyhleHAoZGZfbWVyZ2VkX20kYmFyX20pLCBzdGFydCA9IGMoc3RhcnRfbV95ZWFyLCBzdGFydF9tX21vbnRoKSwgZnJlcXVlbmN5ID0gMTIpDQoNCmBgYA0KDQpgYGB7cn0NCiMgVmVyaWZ5IHRoZSBjcmVhdGVkIHRpbWUgc2VyaWVzDQpwYXIobWZyb3c9YygxLDEpKQ0KcGxvdChzYWxlc19kX3RzKQ0KcGxvdChzYWxlc193X3RzKQ0KcGxvdChzYWxlc19tX3RzKQ0KDQoNCnBsb3QoZm9vZF9kX3RzKQ0KcGxvdChmb29kX3dfdHMpDQpwbG90KGZvb2RfbV90cykNCg0KcGxvdChiYXJfZF90cykNCnBsb3QoYmFyX3dfdHMpDQpwbG90KGJhcl9tX3RzKQ0KYGBgDQoNCkhlcmUgd2UgZmlsbCB0aGUgc2FsZXMgPSAwIHZhbHVlcyB3aXRoIHRoZSBtZWFuIG9mIHRoZSB0d28gYWRqYWNlbnQgZGF0ZXMuIFRoaXMgaW4gb3JkZXIgdG8gaGF2ZSBzbW9vdGhlciBtb2RlbHMuDQpUaGUgZGF0ZXMgd2l0aCBzYWxlcyA9IDAgYXJlIGRhdGVzIHRoYXQgYXJlIG5hdGlvbmFsIGhvbGlkYXkgbGlrZSBjaHJpc3RtYXMgb3IgbmV3IHllYXJzLCBvciBpbnZlbnRvcnkgZGF5IGluIHdoaWNoIHRoZSBraXRjaGVuIGNhbm5vdCBvcGVyYXRlIHNvIHRoZSBzYWxlcyBhcmUgMC4NCmBgYHtyfQ0KIyBGdW5jdGlvbiB0byByZXBsYWNlIDFzIHdpdGggdGhlIG1lYW4gb2YgcHJldmlvdXMgYW5kIG5leHQgb2JzZXJ2YXRpb25zDQpmaWxsX29uZXMgPC0gZnVuY3Rpb24odHNfZGF0YSkgew0KICAjIENvbnZlcnQgdGltZSBzZXJpZXMgdG8gbnVtZXJpYyB2ZWN0b3INCiAgdHNfdmVjIDwtIGFzLm51bWVyaWModHNfZGF0YSkNCiAgDQogICMgTG9vcCB0aHJvdWdoIGFuZCByZXBsYWNlIDFzDQogIGZvciAoaSBpbiBzZXFfYWxvbmcodHNfdmVjKSkgew0KICAgIGlmICh0c192ZWNbaV0gPT0gMSkgew0KICAgICAgIyBDaGVjayBib3VuZGFyaWVzIHRvIGF2b2lkIGluZGV4aW5nIGlzc3Vlcw0KICAgICAgcHJldl92YWwgPC0gaWZlbHNlKGkgPiAxLCB0c192ZWNbaSAtIDFdLCBOQSkNCiAgICAgIG5leHRfdmFsIDwtIGlmZWxzZShpIDwgbGVuZ3RoKHRzX3ZlYyksIHRzX3ZlY1tpICsgMV0sIE5BKQ0KICAgICAgDQogICAgICAjIFJlcGxhY2Ugd2l0aCBtZWFuIG9mIHByZXZpb3VzIGFuZCBuZXh0LCBpZ25vcmluZyBOQQ0KICAgICAgdHNfdmVjW2ldIDwtIG1lYW4oYyhwcmV2X3ZhbCwgbmV4dF92YWwpLCBuYS5ybSA9IFRSVUUpDQogICAgfQ0KICB9DQogIA0KICAjIFJldHVybiBhcyB0aW1lIHNlcmllcyB3aXRoIG9yaWdpbmFsIGF0dHJpYnV0ZXMNCiAgdHModHNfdmVjLCBzdGFydCA9IHN0YXJ0KHRzX2RhdGEpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3kodHNfZGF0YSkpDQp9DQoNCiMgQXBwbHkgdGhlIGZ1bmN0aW9uIA0Kc2FsZXNfZF90cyA8LSBmaWxsX29uZXMoc2FsZXNfZF90cykNCnNhbGVzX3dfdHMgPC0gZmlsbF9vbmVzKHNhbGVzX3dfdHMpDQpzYWxlc19tX3RzIDwtIGZpbGxfb25lcyhzYWxlc19tX3RzKQ0KDQoNCmZvb2RfZF90cyA8LSBmaWxsX29uZXMoZm9vZF9kX3RzKQ0KZm9vZF93X3RzIDwtIGZpbGxfb25lcyhmb29kX3dfdHMpDQpmb29kX21fdHMgPC0gZmlsbF9vbmVzKGZvb2RfbV90cykNCg0KYmFyX2RfdHMgPC0gZmlsbF9vbmVzKGJhcl9kX3RzKQ0KYmFyX3dfdHMgPC0gZmlsbF9vbmVzKGJhcl93X3RzKQ0KYmFyX21fdHMgPC0gZmlsbF9vbmVzKGJhcl9tX3RzKQ0KDQpgYGANCg0KIyMjIEJhc3MgTW9kZWwNCg0KYGBge3J9DQojIFNvbWUgc2ltcGxlIHBsb3RzDQpwbG90KHNhbGVzX21fdHMpDQpwbG90KGN1bXN1bShzYWxlc19tX3RzKSkgI1JldHVybnMgYSB2ZWN0b3Igd2hvc2UgZWxlbWVudHMgYXJlIHRoZSBjdW11bGF0aXZlIHN1bXMNCmBgYA0KDQpgYGB7cn0NCiMgQmFzcyBtb2RlbA0KYm1fbTwtQk0oc2FsZXNfbV90cyxkaXNwbGF5ID0gVCkgIyBzaG93IGdyYXBoaWNhbCB2aWV3IG9mIHJlc3VsdHMgLyBkaXNwbGF5ID0gVHJ1ZQ0KDQpzdW1tYXJ5KGJtX20pDQpgYGANCg0KYGBge3J9DQpibV9tJGNvZWZmaWNpZW50c1snbSddIC0gc3VtKHNhbGVzX21fdHMpDQpgYGANCkFjY29yZGluZyB0byB0aGlzLCB0aGVyZSBhcmUgb25seSAxbSBjb3AgbGVmdCB0byBzZWxsLCB0aGlzIGlzIGxlc3MgdGhhbiBhIHllYXIgLyBzZWVtcyB3cm9uZy4gRml0cyB3ZWxsIGJ1dCB0aGUgMzAtIG9ud2FyZCBpcyB3aWVyZCArIHNhbGVzIG1pZ2h0IG5vdCBiZSBkZWNsaW5pbmcgeWV0LiBTdGlsbCByZWZsZWN0cyB0aGUgaW5ub3ZhdGlvbiBhbmQgY29weWluZyBpbiBzb21lIHNlbnNlDQogDQpBbHNvIHRoZSByZXN0YXVyYW50cyByZWx5IGluIHdvcmQgb2YgbW91dGggdG8gcmVhY2ggZnVsbCBzdGFnZQ0KbSA9IDQuNjY0LjAwMC4wMDAgQ09QLCBpLmUgMSBtbSBFVVIgYXBwcm94LiAvIFRoZSByZXN0YXVyYW50IGhhcyBzb2xkIDMuNTE1Ljc4OC44ODUvIEFjY29yZGluZyB0byB0aGlzIG9ubHkgaW4gMSB5ZWFyIGl0IHNob3VsZCBleHRpbmd1aXNoIHNlbGxzIHAsIGlubm92YXRpb246IDAuODMyJSBpbmRpY2F0ZXMgdGhhdCB0aGUgYWRvcHRpb24gcmF0ZSBkdWUgdG8gZXh0ZXJuYWwgaW5mbHVlbmNlIGlzIHJlbGF0aXZlbHkgbG93LCBidXQgbm90IHVuY29tbW9uIGZvciBtYW55IG1hcmtldHMuIC0gaXQgaXMgYWN0dWFsbHkgcmVsYXRpdmx5IGlubm92YXRpdmUgcTogKDguOTYlKSBzdWdnZXN0cyB0aGF0IGltaXRhdGlvbiBwbGF5cyBhIGxhcmdlciByb2xlIHRoYW4gaW5ub3ZhdGlvbiBpbiBkcml2aW5nIGFkb3B0aW9uIGluIHRoaXMgbWFya2V0DQoNCg0KDQpgYGB7cn0NCnByZWRfYm1fbTwtIHByZWRpY3QoYm1fbSwgbmV3eD1jKDE6bGVuZ3RoKHNhbGVzX21fdHMpKSkNCnByZWRfYm1fbSA8LSB0cyhwcmVkX2JtX20sIHN0YXJ0ID0gc3RhcnQoc2FsZXNfbV90cyksIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeShzYWxlc19tX3RzKSkNCnByZWQuaW5zdF9ibV9tIDwtIG1ha2UuaW5zdGFudGFuZW91cyhwcmVkX2JtX20pDQpwcmVkLmluc3RfYm1fbSA8LSB0cyhwcmVkLmluc3RfYm1fbSwgc3RhcnQgPSBzdGFydChzYWxlc19tX3RzKSwgZnJlcXVlbmN5ID0gZnJlcXVlbmN5KHNhbGVzX21fdHMpKQ0KDQojIHBsb3QNCnBsb3Qoc2FsZXNfbV90cywgdHlwZSA9ICJwIiwgY29sID0gImJsYWNrIiwgcGNoID0gMTYsIGNleCA9IDAuNywNCiAgICAgeGxhYiA9ICJNb250aCIsIHlsYWIgPSAiTW9udGhseSBTYWxlcyIsIG1haW4gPSAiQWN0dWFsIHZzIEZpdHRlZCBTYWxlcyIpDQoNCiMgQWRkIHRoZSBmaXR0ZWQgdmFsdWVzIGFzIGEgbGluZQ0KbGluZXMocHJlZC5pbnN0X2JtX20sIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQ0KDQojIEFkZCBhIGxlZ2VuZA0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiQWN0dWFsIFZhbHVlcyIsICJGaXR0ZWQgVmFsdWVzIiksDQogICAgICAgY29sID0gYygiYmxhY2siLCAicmVkIiksIHBjaCA9IGMoMTYsIE5BKSwgbHR5ID0gYyhOQSwgMSksIGx3ZCA9IGMoTkEsIDIpKQ0KYGBgDQoNCmBgYHtyfQ0KIyBjaGVjayByZXNpZHVhbHMNCnJlc19ibV9tIDwtIHNhbGVzX21fdHMgLSBwcmVkLmluc3RfYm1fbQ0KdHNkaXNwbGF5KHJlc19ibV9tKQ0KYGBgDQpSZXNpZHVhbHMgaGF2ZSBzb21lIHN0cnVjdHVyZSBhbmQgMiBsYWcgaGFzIGNvcnJlbGF0aW9uLg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIFJNU0UgZm9yIEJhc3MgTW9kZWwgcHJlZGljdGlvbnMNCnJtc2VfYm1fbSA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX21fdHMsIHByZWRpY3RlZCA9IHByZWQuaW5zdF9ibV9tKQ0KDQojIFByaW50IHRoZSBSTVNFDQpjYXQoIlJNU0UgZm9yIEJhc3MgTW9kZWwgUHJlZGljdGlvbnM6Iiwgcm1zZV9ibV9tLCAiXG4iKQ0KDQpgYGANCg0KYGBge3J9DQpibV93PC1CTShzYWxlc193X3RzLGRpc3BsYXkgPSBUKSAjIHNob3cgZ3JhcGhpY2FsIHZpZXcgb2YgcmVzdWx0cyAvIGRpc3BsYXkgPSBUcnVlDQpzdW1tYXJ5KGJtX3cpDQpibV93JGNvZWZmaWNpZW50c1snbSddIC0gc3VtKHNhbGVzX3dfdHMpDQojIHJlc3VsdHMgYXJlIHNpbWlsYXIgaW4gdGVybXMgb2YgbSwgcCBhbmQgdyBhcmUgaW4gb3RoZXIgc2NhbGUgDQojYmVjYXVzZSB0aGV5IGFyZSBpbiBkaWZmZXJlbnQgdGltZSBzdGFtcA0KYm1fbSRjb2VmZmljaWVudHNbJ3EnXSAvIGJtX3ckY29lZmZpY2llbnRzWydxJ10gIyB0aGV5IGFyZSBhcHByb3ggNCB0aW1lcw0KYm1fbSRjb2VmZmljaWVudHNbJ3AnXSAvIGJtX3ckY29lZmZpY2llbnRzWydwJ10gIyB0aGV5IGFyZSBhcHByb3ggNCB0aW1lcw0KIyB3aGljaCBtYWtlcyBzZW5zZQ0KYGBgDQpDb2VmZmljaWVudHMgYXJlIGFwcHJveGltYXRseSA0IHRpbWVzIHRoZSBvbmVzIG9mIHRoZSBtb250aGx5IG1vZGVsLCBtYWtpbmcgc2Vuc2UgYmVjYXVzZSB0aGVyZSBhcmUgNCB3ZWVrcyBpbiBhIG1vbnRoLiBXaGlsZSBtYXJrZXQgcG90ZW50aWFsIGlzIHNpbWlsYXIuDQoNCmBgYHtyfQ0KIyBQcmVkaWN0aW9uDQpwcmVkX2JtX3c8LSBwcmVkaWN0KGJtX3csIG5ld3g9YygxOmxlbmd0aChzYWxlc193X3RzKSkpDQpwcmVkX2JtX3cgPC0gdHMocHJlZF9ibV93LCBzdGFydCA9IHN0YXJ0KHNhbGVzX3dfdHMpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3koc2FsZXNfd190cykpDQpwcmVkLmluc3RfYm1fdyA8LSBtYWtlLmluc3RhbnRhbmVvdXMocHJlZF9ibV93KQ0KcHJlZC5pbnN0X2JtX3cgPC0gdHMocHJlZC5pbnN0X2JtX3csIHN0YXJ0ID0gc3RhcnQoc2FsZXNfd190cyksIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeShzYWxlc193X3RzKSkNCg0KIyBwbG90DQpwbG90KHNhbGVzX3dfdHMsIHR5cGUgPSAicCIsIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2LCBjZXggPSAwLjcsDQogICAgIHhsYWIgPSAiV2VlayIsIHlsYWIgPSAiV2Vla2x5IFNhbGVzIiwgbWFpbiA9ICJBY3R1YWwgdnMgRml0dGVkIFNhbGVzIikNCg0KIyBBZGQgdGhlIGZpdHRlZCB2YWx1ZXMgYXMgYSBsaW5lDQpsaW5lcyhwcmVkLmluc3RfYm1fdywgY29sID0gInJlZCIsIGx3ZCA9IDIpDQoNCiMgQWRkIGEgbGVnZW5kDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJBY3R1YWwgVmFsdWVzIiwgIkZpdHRlZCBWYWx1ZXMiKSwNCiAgICAgICBjb2wgPSBjKCJibGFjayIsICJyZWQiKSwgcGNoID0gYygxNiwgTkEpLCBsdHkgPSBjKE5BLCAxKSwgbHdkID0gYyhOQSwgMikpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBjaGVjayByZXNpZHVhbHMNCnJlc19ibV93IDwtIHNhbGVzX3dfdHMgLSBwcmVkLmluc3RfYm1fdw0KdHNkaXNwbGF5KHJlc19ibV93KQ0KYGBgDQoNClJlc2lkdWFscyBoYXZlIHNvbWUgc3RydWN0dXJlIGFuZCAyIGxhZyBoYXMgY29ycmVsYXRpb24sIHdpdGggY2xlYXIgdHJlbmQgYW5kIHN0cnVjdHVyZSBpbiB0aGUgcmVzaWR1YWxzDQoNCmBgYHtyfQ0KIyBSTVNFDQojIENhbGN1bGF0ZSBSTVNFIGZvciBCYXNzIE1vZGVsIHByZWRpY3Rpb25zDQpybXNlX2JtX3cgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc193X3RzLCBwcmVkaWN0ZWQgPSBwcmVkLmluc3RfYm1fdykNCg0KIyBQcmludCB0aGUgUk1TRQ0KY2F0KCJSTVNFIGZvciBCYXNzIE1vZGVsIFByZWRpY3Rpb25zOiIsIHJtc2VfYm1fdywgIlxuIikNCg0KYGBgDQpgYGB7cn0NCmJtX2QgPC0gQk0oDQogIHNhbGVzX2RfdHMsDQogIHByZWxpbWVzdGltYXRlcyA9IGMoMS4yICogc3VtKHNhbGVzX2RfdHMpLCAwLjAwNSwgMC41KSwgIyBBZGp1c3QgdGhlc2UgZXN0aW1hdGVzDQogIGRpc3BsYXkgPSBUUlVFDQopDQoNCg0Kc3VtbWFyeShibV9kKQ0KYm1fZCRjb2VmZmljaWVudHNbJ20nXSAtIHN1bShzYWxlc19kX3RzKQ0KIyByZXN1bHRzIGFyZSBzaW1pbGFyIGluIHRlcm1zIG9mIG0sIHAgYW5kIHcgYXJlIGluIG90aGVyIHNjYWxlIA0KI2JlY2F1c2UgdGhleSBhcmUgaW4gZGlmZmVyZW50IHRpbWUgc3RhbXANCmJtX3ckY29lZmZpY2llbnRzWydxJ10gLyBibV9kJGNvZWZmaWNpZW50c1sncSddICMgdGhleSBhcmUgYXBwcm94IDcgdGltZXMNCmJtX3ckY29lZmZpY2llbnRzWydwJ10gLyBibV9kJGNvZWZmaWNpZW50c1sncCddICMgdGhleSBhcmUgYXBwcm94IDcgdGltZXMNCg0KYGBgDQpDb2VmZmljaWVudHMgYXJlIGFwcHJveGltYXRlbHkgMTo3IHNjYWxlIG9mIHRoZSBvbmVzIGluIHRoZSB3ZWVrbHkgbW9kZWwsIG1ha2luZyBzZW5zZS4NClRoZSBtYXJrZXQgcG90ZW50aWFsIGlzIGFsc28gc2ltaWxhciBpbiBvcmRlciBvZiBtYWduaXR1ZGUuDQoNCmBgYHtyfQ0KIyBQcmVkaWN0aW9uDQpwcmVkX2JtX2QgPC0gcHJlZGljdChibV9kLCBuZXd4ID0gYygxOmxlbmd0aChzYWxlc19kX3RzKSkpDQpwcmVkX2JtX2QgPC0gdHMocHJlZF9ibV9kLCBzdGFydCA9IHN0YXJ0KHNhbGVzX2RfdHMpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3koc2FsZXNfZF90cykpDQpwcmVkLmluc3RfYm1fZCA8LSBtYWtlLmluc3RhbnRhbmVvdXMocHJlZF9ibV9kKQ0KcHJlZC5pbnN0X2JtX2QgPC0gdHMocHJlZC5pbnN0X2JtX2QsIHN0YXJ0ID0gc3RhcnQoc2FsZXNfZF90cyksIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeShzYWxlc19kX3RzKSkNCg0KIyBQbG90IGFjdHVhbCB2cyBmaXR0ZWQgc2FsZXMgZm9yIGRhaWx5IGRhdGENCnBsb3Qoc2FsZXNfZF90cywgdHlwZSA9ICJwIiwgY29sID0gImJsYWNrIiwgcGNoID0gMTYsIGNleCA9IDAuNywNCiAgICAgeGxhYiA9ICJEYXkiLCB5bGFiID0gIkRhaWx5IFNhbGVzIiwgbWFpbiA9ICJBY3R1YWwgdnMgRml0dGVkIFNhbGVzIChEYWlseSkiKQ0KDQojIEFkZCB0aGUgZml0dGVkIHZhbHVlcyBhcyBhIGxpbmUNCmxpbmVzKHByZWQuaW5zdF9ibV9kLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCg0KIyBBZGQgYSBsZWdlbmQNCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIkFjdHVhbCBWYWx1ZXMiLCAiRml0dGVkIFZhbHVlcyIpLA0KICAgICAgIGNvbCA9IGMoImJsYWNrIiwgInJlZCIpLCBwY2ggPSBjKDE2LCBOQSksIGx0eSA9IGMoTkEsIDEpLCBsd2QgPSBjKE5BLCAyKSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIENoZWNrIHJlc2lkdWFscw0KcmVzX2JtX2QgPC0gc2FsZXNfZF90cyAtIHByZWQuaW5zdF9ibV9kDQp0c2Rpc3BsYXkocmVzX2JtX2QpDQpgYGANCg0KUmVzaWR1YWxzIGRvbiBub3Qgc2VlbSBzdGF0aW9uYXJ5LCBvciBhdCBsZWFzdCB0aGV5IGhhdmUgYSBsb3Qgb2YgYXV0b2NvcnJlbGF0aW9uLg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIFJNU0UgZm9yIEJhc3MgTW9kZWwgcHJlZGljdGlvbnMgKGRhaWx5IGRhdGEpDQpybXNlX2JtX2QgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19kX3RzLCBwcmVkaWN0ZWQgPSBwcmVkLmluc3RfYm1fZCkNCg0KIyBQcmludCB0aGUgUk1TRQ0KY2F0KCJSTVNFIGZvciBEYWlseSBCYXNzIE1vZGVsIFByZWRpY3Rpb25zOiIsIHJtc2VfYm1fZCwgIlxuIikNCg0KYGBgDQoNCg0KDQojIyMjIExpbWl0YXRpb24gb2Ygb2YgdGhlIEJhc3MgTW9kZWwNCg0KLSAgIEJhc3MgbW9kZWwgYXNzdW1lcyB0aGF0IGV2ZXJ5IHByb2R1Y3Qgc3VjY2VlZHMgYW5kIHRoZSBzYWxlcw0KICAgIHNhdHVyYXRlIHRvIHRoZSBzdGVhZHkgc3RhdGUgbGV2ZWwuIEhvd2V2ZXIsIG1vc3QgbmV3IHByb2R1Y3RzIGZhaWwNCiAgICBpbiByZWFsaXR5Lg0KDQotICAgVGhlIG1hcmtldCBwb3RlbnRpYWwgKm0qIGlzIGNvbnN0YW50IGFsb25nIHRoZSB3aG9sZSBsaWZlIGN5Y2xlLg0KDQotICAgQmFzcyBtb2RlbCBwcmVkaWN0aW9ucyB3b3JrcyB3ZWxsIG9ubHkgYWZ0ZXIgdGhlIHNjYWxlIGluZmxlY3Rpb24NCiAgICBwb2ludC4gaWYgc2FsZXMgb2YgYSBjYXRlZ29yeSBnb2VzIHVwIGFuZCB1cCBsaWtlIGEgSi1jdXJ2ZSwgaXQgY2FuDQogICAgb3ZlciBlc3RpbWF0ZSB0aGUgb3ZlcmFsbCBtYXJrZXQgc2l6ZS4NCg0KLSAgIEl0IGlzIGEgbW9kZWwgZm9yIHByb2R1Y3RzIHdpdGggYSBsaW1pdGVkIGxpZmUgY3ljbGU6IG5lZWRzIGENCiAgICBoeXBvdGhlc2lzLg0KDQotICAgQW5vdGhlciBkcmF3YmFjayBvZiBCYXNzIG1vZGVsIGlzIHRoYXQgdGhlIGRpZmZ1c2lvbiBwYXR0ZXJuIGluIG5vdA0KICAgIGFmZmVjdGVkIGJ5IG1hcmtldGluZyBtaXggdmFyaWFibGVzIGxpa2UgcHJpY2Ugb3IgYWR2ZXJ0aXNpbmcuDQoNClRoZSBnZW5lcmFsaXplZCBCYXNzIG1vZGVsIGV4dGVuZHMgdGhlIG9yaWdpbmFsIEJhc3MgbW9kZWwgYWxsb3dpbmcgdGhlDQpyb2xlcyBvZiBtYXJrZXRpbmcgbWl4IHZhbHVlLg0KDQojIyMgR2VuZXJhbGl6ZWQgQmFzcyBNb2RlbA0KDQpCYXNzIG1vZGVsIGlzIHVzZWQgdG8gZm9yZWNhc3QgdGhlIGFkb3B0aW9uIG9mIGEgbmV3IHByb2R1Y3QgYW5kIHRvDQpwcmVkaWN0IHRoZSBzYWxlcywgc2luY2UgaXQgZGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2YgdGhlIGN1cnZlIG9mIGEgbW9kZWwNCnRoYXQgcmVwcmVzZW50IHRoZSBjdW11bGF0aXZlIGFkb3B0aW9uIG9mIGEgbmV3IHByb2R1Y3QuIFRoZSBHZW5lcmFsaXplZA0KQmFzcyBtb2RlbCBleHRlbmRzIHRoZSBvcmlnaW5hbCBCYXNzIG1vZGVsIGJ5IGluY29ycG9yYXRpbmcgbWFya2V0aW5nDQptaXggdmFyaWFibGVzLiBXZSBjYW4ga25vdyB0aGUgZWZmZWN0IG9mIHByaWNpbmcsIHByb21vdGlvbnMgb24gdGhlIG5ldw0KcHJvZHVjdCBkaWZmdXNpb24gY3VydmUuIEl0IGlzIG1vcmUgZmxleGlibGUgdGhhbiB0aGUgb3JpZ2luYWwgQmFzcw0KbW9kZWwuDQoNCmBgYHtyfQ0KDQptIDwtIDQuNDUxNTcwZSswOQ0KcCA8LSA4LjQ3MjkxN2UtMDMNCnEgPC0gOS40MTU2MjVlLTAyDQoNCkdCTV9tb250aGx5X3NhbGVzIDwtIEdCTSgNCiAgc2FsZXNfbV90cywgDQogIHNob2NrID0gJ2V4cCcsIA0KICBuc2hvY2sgPSAxLA0KICAjcHJlbGltZXN0aW1hdGVzID0gYyhtLHAscSwgMTIsIDAuMSwgLTAuMSkNCiAgcHJlbGltZXN0aW1hdGVzID0gYyhtLHAscSwgMTAsIDAuMSwgMikNCiAgI3ByZWxpbWVzdGltYXRlcyA9IGMobSxwLHEsIDExLCAxNSwgLTAuMSkNCiAgKQ0KDQpzdW1tYXJ5KEdCTV9tb250aGx5X3NhbGVzKQ0KDQpwcmVkX0dCTV9tb250aGx5X3NhbGVzPC0gcHJlZGljdChHQk1fbW9udGhseV9zYWxlcywgbmV3eD1jKDE6NjApKQ0KcHJlZF9HQk1fbW9udGhseV9zYWxlcy5pbnN0PC0gbWFrZS5pbnN0YW50YW5lb3VzKHByZWRfR0JNX21vbnRobHlfc2FsZXMpDQpgYGANCg0KIyMjIEd1c2VvLUd1aWRvbGluIE1vZGVsDQoNCmBgYHtyfQ0KIyBNb250bHkgbW9kZWwNCmdnbTEgPC0gR0dNKHNhbGVzX21fdHMsIG10PSdiYXNlJywgZGlzcGxheSA9IFQpDQpnZ20yIDwtIEdHTShzYWxlc19tX3RzLCBtdD0gZnVuY3Rpb24oeCkgcGNoaXNxKHgsMTApLGRpc3BsYXkgPSBUKQ0Kc3VtbWFyeShnZ20xKQ0Kc3VtbWFyeShnZ20yKQ0KIyB0cnkgZGlmZmVyZW50IGZ1bmN0aW9ucyBmb3IgbWFya2V0IHBvdGVudGlhbA0KDQpnZ20zIDwtIEdHTShzYWxlc19tX3RzLCBtdD0gZnVuY3Rpb24oeCkgbG9nKHgpLGRpc3BsYXkgPSBUKQ0KZ2dtNCA8LSBHR00oc2FsZXNfbV90cywgbXQ9IGZ1bmN0aW9uKHgpICh4KSoqKDEvMS4wNSksZGlzcGxheSA9IFQpDQpzdW1tYXJ5KGdnbTMpDQpzdW1tYXJ5KGdnbTQpDQpgYGANCg0KDQoNCksgXDwtIDcuNjgzNzg1ZSswOQ0KDQpwYyBcPC0gMi42OTg2MTNlLTAyDQoNCnFjIFw8LSAyLjU4MjQxMmUtMDENCg0KcHMgXDwtIDcuNzMxNzYzZS0wMw0KDQpxcyBcPC0gNC41MDgyMDJlLTAyDQoNCmBgYHtyfQ0KIyBwcmVkaWN0aW9ucw0KcHJlZF9nZ21fbSA8LSBwcmVkaWN0KGdnbTEsIG5ld3ggPSBjKDE6bGVuZ3RoKHNhbGVzX21fdHMpKSkNCnByZWRfZ2dtX20gPC0gdHMocHJlZF9nZ21fbSwgc3RhcnQgPSBzdGFydChzYWxlc19tX3RzKSwgZnJlcXVlbmN5ID0gZnJlcXVlbmN5KHNhbGVzX21fdHMpKQ0KcHJlZC5pbnN0X2dnbV9tIDwtIG1ha2UuaW5zdGFudGFuZW91cyhwcmVkX2dnbV9tKQ0KcHJlZC5pbnN0X2dnbV9tIDwtIHRzKHByZWQuaW5zdF9nZ21fbSwgc3RhcnQgPSBzdGFydChzYWxlc19tX3RzKSwgZnJlcXVlbmN5ID0gZnJlcXVlbmN5KHNhbGVzX21fdHMpKQ0KDQojIFBsb3QgYWN0dWFsIHZzIGZpdHRlZCBzYWxlcyBmb3IgbW9udGhseSBkYXRhDQpwbG90KHNhbGVzX21fdHMsIHR5cGUgPSAicCIsIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2LCBjZXggPSAwLjcsDQogICAgIHhsYWIgPSAiTW9udGgiLCB5bGFiID0gIk1vbnRobHkgU2FsZXMiLCBtYWluID0gIkFjdHVhbCB2cyBGaXR0ZWQgU2FsZXMgKEdHTSBNb2RlbCkiKQ0KDQojIEFkZCB0aGUgZml0dGVkIHZhbHVlcyBhcyBhIGxpbmUNCmxpbmVzKHByZWQuaW5zdF9nZ21fbSwgY29sID0gInJlZCIsIGx3ZCA9IDIpDQoNCiMgQWRkIGEgbGVnZW5kDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJBY3R1YWwgVmFsdWVzIiwgIkZpdHRlZCBWYWx1ZXMgKEdHTSkiKSwNCiAgICAgICBjb2wgPSBjKCJibGFjayIsICJyZWQiKSwgcGNoID0gYygxNiwgTkEpLCBsdHkgPSBjKE5BLCAxKSwgbHdkID0gYyhOQSwgMikpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KI0FuYWx5c2lzIG9mIHJlc2lkdWFscw0KcmVzX0dHTV9tPC0gc2FsZXNfbV90cyAtIHByZWQuaW5zdF9nZ21fbQ0KdHNkaXNwbGF5KHJlc19HR01fbSkNCmBgYA0KUmVzaWR1YWxzIGxvb2sgc3RhdGlvbmFyeSBmb3IgdGhpcyBtb2RlbA0KDQpgYGB7cn0NCiMgUmVzaWR1YWxzIHNvbWVob3cgYXJlIGtpbmQgb2Ygc3RhdGlvbmFyeQ0KIyBjaGVjayBmb3Igc3RhdGlvbmFyaXR5IG9mIHJlc2lkdWFscw0KYWRmX3Rlc3QgPC0gYWRmLnRlc3QocmVzX0dHTV9tKQ0KcHJpbnQoYWRmX3Rlc3QpICMgaWYgcC12YWwgPCBhbHBoYSwgc2VyaWVzIHN0YXRpb25hcnkNCiMgc28gd2l0aCB0aGlzIG1vZGVsIHdlIGFjaGlldmUgc3RhdGlvbmFyeSBzZXJpZXMNCg0KIyBjaGVjayBmb3IgYXV0b2NvcnJlbGF0aW9uIGluIHJlc2lkdWFscw0KQm94LnRlc3QocmVzX0dHTV9tLCBsYWcgPSAxMCwgdHlwZSA9ICJManVuZy1Cb3giKSAjIGgwIHJlcyBpbmRlcA0KIyBwLXZhbCA+IGFscGhhID0+IGZhaWwgdG8gcmVqZWN0IGgwLCBzbyByZXNpZHVhbHMgc2VlbSBpbmRlcA0KDQpgYGANClJlc2lkdWFscyBhcmUgbGlrZWxleSBzdGF0aW9uYXJ5DQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgUk1TRSBmb3IgZ2dtMQ0Kcm1zZV9nZ20xIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfbV90cywgcHJlZGljdGVkID0gcHJlZC5pbnN0X2dnbV9tKQ0KDQojIFByaW50IFJNU0UgZm9yIGdnbTENCmNhdCgiUk1TRSBmb3IgR0dNIE1vZGVsIDEgKEJhc2UpOiIsIHJtc2VfZ2dtMSwgIlxuIikNCg0KYGBgDQpgYGB7cn0NCiMgV2Vla2x5DQpnZ20xX3cgPC0gR0dNKHNhbGVzX3dfdHMsIG10PSdiYXNlJywgZGlzcGxheSA9IFQpDQpnZ20yX3cgPC0gR0dNKHNhbGVzX3dfdHMsIG10PSBmdW5jdGlvbih4KSBwY2hpc3EoeCwyNSksZGlzcGxheSA9IFQpDQpzdW1tYXJ5KGdnbTFfdykgIyB0aGlzIG9uZSBpcyBiZXR0ZXINCnN1bW1hcnkoZ2dtMl93KQ0KIyB0cnkgZGlmZmVyZW50IGZ1bmN0aW9ucyBmb3IgbWFya2V0IHBvdGVudGlhbA0KDQpnZ20zX3cgPC0gR0dNKHNhbGVzX3dfdHMsIG10PSBmdW5jdGlvbih4KSBsb2coeCksZGlzcGxheSA9IFQpDQpnZ200X3cgPC0gR0dNKHNhbGVzX3dfdHMsIG10PSBmdW5jdGlvbih4KSAoeCkqKigxLzEuMDUpLGRpc3BsYXkgPSBUKQ0KDQpzdW1tYXJ5KGdnbTNfdykNCnN1bW1hcnkoZ2dtNF93KSAjIGJldHRlciBzaGFwZWQgYnV0IGxlc3Mgc2lnbmlmaWNhbnQNCg0KYGBgDQoNCmBgYHtyfQ0KIyBwcmVkaWN0aW9ucw0KcHJlZF9nZ21fdyA8LSBwcmVkaWN0KGdnbTFfdywgbmV3eCA9IGMoMTpsZW5ndGgoc2FsZXNfd190cykpKQ0KcHJlZF9nZ21fdyA8LSB0cyhwcmVkX2dnbV93LCBzdGFydCA9IHN0YXJ0KHNhbGVzX3dfdHMpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3koc2FsZXNfd190cykpDQpwcmVkLmluc3RfZ2dtX3cgPC0gbWFrZS5pbnN0YW50YW5lb3VzKHByZWRfZ2dtX3cpDQpwcmVkLmluc3RfZ2dtX3cgPC0gdHMocHJlZC5pbnN0X2dnbV93LCBzdGFydCA9IHN0YXJ0KHNhbGVzX3dfdHMpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3koc2FsZXNfd190cykpDQoNCiMgUGxvdCBhY3R1YWwgdnMgZml0dGVkIHNhbGVzIGZvciB3ZWVrbHkgZGF0YQ0KcGxvdChzYWxlc193X3RzLCB0eXBlID0gInAiLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNiwgY2V4ID0gMC43LA0KICAgICB4bGFiID0gIldlZWsiLCB5bGFiID0gIldlZWtseSBTYWxlcyIsIG1haW4gPSAiQWN0dWFsIHZzIEZpdHRlZCBTYWxlcyAoR0dNIE1vZGVsKSIpDQoNCiMgQWRkIHRoZSBmaXR0ZWQgdmFsdWVzIGFzIGEgbGluZQ0KbGluZXMocHJlZC5pbnN0X2dnbV93LCBjb2wgPSAicmVkIiwgbHdkID0gMikNCg0KIyBBZGQgYSBsZWdlbmQNCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIkFjdHVhbCBWYWx1ZXMiLCAiRml0dGVkIFZhbHVlcyAoR0dNKSIpLA0KICAgICAgIGNvbCA9IGMoImJsYWNrIiwgInJlZCIpLCBwY2ggPSBjKDE2LCBOQSksIGx0eSA9IGMoTkEsIDEpLCBsd2QgPSBjKE5BLCAyKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBBbmFseXNpcyBvZiByZXNpZHVhbHMNCnJlc19HR01fdyA8LSBzYWxlc193X3RzIC0gcHJlZC5pbnN0X2dnbV93DQp0c2Rpc3BsYXkocmVzX0dHTV93KQ0KDQoNCiMgQ2hlY2sgZm9yIHN0YXRpb25hcml0eSBvZiByZXNpZHVhbHMNCmFkZl90ZXN0X3cgPC0gYWRmLnRlc3QocmVzX0dHTV93KQ0KcHJpbnQoYWRmX3Rlc3RfdykgIyBpZiBwLXZhbHVlIDwgYWxwaGEsIHNlcmllcyBpcyBzdGF0aW9uYXJ5DQoNCiMgQ2hlY2sgZm9yIGF1dG9jb3JyZWxhdGlvbiBpbiByZXNpZHVhbHMNCmJveF90ZXN0X3cgPC0gQm94LnRlc3QocmVzX0dHTV93LCBsYWcgPSAxMCwgdHlwZSA9ICJManVuZy1Cb3giKQ0KcHJpbnQoYm94X3Rlc3RfdykgIyBpZiBwLXZhbHVlID4gYWxwaGEsIHJlc2lkdWFscyBhcmUgaW5kZXBlbmRlbnQNCg0KYGBgDQpTZXJpZXMgaXMgc3RhdGlvbmFyeSBhY2NvcmRpbmcgdG8gdGVzdHMsIGJ1dCBjbGVhcmx5IGhhcyBzdHJvbmcgYXV0b2NvcnJlbGF0aW9uDQoNCmBgYHtyfQ0KIyBSTVNFDQpybXNlX2dnbV93IDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfd190cywgcHJlZGljdGVkID0gcHJlZC5pbnN0X2dnbV93KQ0KDQojIFByaW50IHRoZSBSTVNFDQpjYXQoIlJNU0UgZm9yIFdlZWtseSBHR00gTW9kZWwgUHJlZGljdGlvbnM6Iiwgcm1zZV9nZ21fdywgIlxuIikNCg0KYGBgDQoNCmBgYHtyfQ0KIyBEYWlseSBHR00NCiMgU2NhbGluZyB0aGUgc2FsZXMgZGF0YQ0Kc2FsZXNfbWluIDwtIG1pbihzYWxlc19kX3RzKQ0Kc2FsZXNfbWF4IDwtIG1heChzYWxlc19kX3RzKQ0Kc2FsZXNfc2NhbGVkIDwtIChzYWxlc19kX3RzIC0gc2FsZXNfbWluKSAvIChzYWxlc19tYXggLSBzYWxlc19taW4pDQoNCiMgVmlldyBzY2FsZWQgZGF0YQ0Kc3VtbWFyeShzYWxlc19zY2FsZWQpDQpwbG90KHNhbGVzX3NjYWxlZCwgdHlwZSA9ICJsIiwgbWFpbiA9ICJTY2FsZWQgRGFpbHkgU2FsZXMiLCB4bGFiID0gIkRheSIsIHlsYWIgPSAiU2NhbGVkIFNhbGVzIikNCg0KYGBgDQpXZSByZS1zY2FsZSB0aGUgZGF0YSBiZWNhdXNlIGVsc2UgdGhlIG1vZGVsIHdvbid0IGNvbnZlcmdlDQoNCmBgYHtyfQ0KIyBGaXQgR0dNIG1vZGVscyB1c2luZyBzY2FsZWQgZGF0YQ0KZ2dtMV9kIDwtIEdHTShzYWxlc19zY2FsZWQsIG10ID0gJ2Jhc2UnLCBkaXNwbGF5ID0gVCkNCmdnbTJfZCA8LSBHR00oc2FsZXNfc2NhbGVkLCBtdCA9IGZ1bmN0aW9uKHgpIHBjaGlzcSh4LCAxMCksIGRpc3BsYXkgPSBUKQ0KZ2dtM19kIDwtIEdHTShzYWxlc19zY2FsZWQsIG10ID0gZnVuY3Rpb24oeCkgbG9nKHgpLCBkaXNwbGF5ID0gVCkNCmdnbTRfZCA8LSBHR00oc2FsZXNfc2NhbGVkLCBtdCA9IGZ1bmN0aW9uKHgpICh4KV4oMS8xLjA1KSwgZGlzcGxheSA9IFQpDQoNCiMgU3VtbWFyaXplIG1vZGVscw0Kc3VtbWFyeShnZ20xX2QpICAjIEJhc2UgbW9kZWwNCnN1bW1hcnkoZ2dtMl9kKSAgIyBDaGktc3F1YXJlZA0Kc3VtbWFyeShnZ20zX2QpICAjIExvZyB0cmFuc2Zvcm1hdGlvbg0Kc3VtbWFyeShnZ200X2QpICAjIFBvd2VyIHRyYW5zZm9ybWF0aW9uDQoNCmBgYA0KDQpQcmVkaWN0IG9uIHRoZSBiZXN0IG1vZGVsIGJhc2VkIG9uIGZpdCBhbmQgcC12YWx1ZXMNCldlIHNlbGVjdCBtb2RlbCAxDQpgYGB7cn0NCiMgUHJlZGljdGlvbiB1c2luZyBHR00gbW9kZWwNCnByZWRfZ2dtX2QgPC0gcHJlZGljdChnZ20xX2QsIG5ld3ggPSBjKDE6bGVuZ3RoKHNhbGVzX3NjYWxlZCkpKQ0KcHJlZF9nZ21fZCA8LSB0cyhwcmVkX2dnbV9kLCBzdGFydCA9IHN0YXJ0KHNhbGVzX3NjYWxlZCksIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeShzYWxlc19zY2FsZWQpKQ0KcHJlZC5pbnN0X2dnbV9kIDwtIG1ha2UuaW5zdGFudGFuZW91cyhwcmVkX2dnbV9kKQ0KcHJlZC5pbnN0X2dnbV9kIDwtIHRzKHByZWQuaW5zdF9nZ21fZCwgc3RhcnQgPSBzdGFydChzYWxlc19zY2FsZWQpLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3koc2FsZXNfc2NhbGVkKSkNCg0KIyBSZS1zY2FsZSBwcmVkaWN0aW9ucyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBzY2FsZQ0KcHJlZF9vcmlnaW5hbF9zY2FsZSA8LSAocHJlZC5pbnN0X2dnbV9kICogKHNhbGVzX21heCAtIHNhbGVzX21pbikpICsgc2FsZXNfbWluDQoNCiMgUGxvdCBhY3R1YWwgdnMgZml0dGVkIHNhbGVzIChvcmlnaW5hbCBzY2FsZSkNCnBsb3Qoc2FsZXNfZF90cywgdHlwZSA9ICJwIiwgY29sID0gImJsYWNrIiwgcGNoID0gMTYsIGNleCA9IDAuNywNCiAgICAgeGxhYiA9ICJEYXkiLCB5bGFiID0gIkRhaWx5IFNhbGVzIiwgbWFpbiA9ICJBY3R1YWwgdnMgRml0dGVkIFNhbGVzIChPcmlnaW5hbCBTY2FsZSkiKQ0KbGluZXMocHJlZF9vcmlnaW5hbF9zY2FsZSwgY29sID0gInJlZCIsIGx3ZCA9IDIpDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJBY3R1YWwgVmFsdWVzIiwgIkZpdHRlZCBWYWx1ZXMgKEdHTSwgT3JpZ2luYWwgU2NhbGUpIiksDQogICAgICAgY29sID0gYygiYmxhY2siLCAicmVkIiksIHBjaCA9IGMoMTYsIE5BKSwgbHR5ID0gYyhOQSwgMSksIGx3ZCA9IGMoTkEsIDIpKQ0KDQpgYGANCg0KYGBge3J9DQojIEFuYWx5c2lzIG9mIHJlc2lkdWFscw0KcmVzX0dHTV9kIDwtIHNhbGVzX2RfdHMgLSBwcmVkX29yaWdpbmFsX3NjYWxlDQp0c2Rpc3BsYXkocmVzX0dHTV9kLCBtYWluID0gIlJlc2lkdWFscyBvZiBHR00gTW9kZWwiKQ0KDQpgYGANClJlc2lkdWFscyBkb250IGxvb2sgc3RhdGlvbmFyeQ0KDQpgYGB7cn0NCiMgQ2hlY2sgZm9yIHN0YXRpb25hcml0eSBvZiByZXNpZHVhbHMNCmFkZl90ZXN0X2QgPC0gYWRmLnRlc3QocmVzX0dHTV9kKQ0KcHJpbnQoYWRmX3Rlc3RfZCkgICMgSWYgcC12YWx1ZSA8IGFscGhhLCBzZXJpZXMgaXMgc3RhdGlvbmFyeQ0KIyBhY2NvcmRpbmcgdG8gdGhpcywgdGhleSBhcmUgc3RhdGlvbmFyeQ0KDQojIENoZWNrIGZvciBhdXRvY29ycmVsYXRpb24gaW4gcmVzaWR1YWxzDQpib3hfdGVzdF9kIDwtIEJveC50ZXN0KHJlc19HR01fZCwgbGFnID0gMTAsIHR5cGUgPSAiTGp1bmctQm94IikNCnByaW50KGJveF90ZXN0X2QpICAjIElmIHAtdmFsdWUgPiBhbHBoYSwgcmVzaWR1YWxzIGFyZSBpbmRlcA0KDQpgYGANClJlc2lkdWFscyBsb29rIHN0YXRpb25hcnkgaW4gdGhlIHRlc3QgYnV0IGhleSBoYXZlIHNlcmlhbCBjb3JyZWxhdGlvbg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIFJNU0UgZm9yIEdHTSBtb2RlbCBwcmVkaWN0aW9ucyAob3JpZ2luYWwgc2NhbGUpDQpybXNlX2dnbV9kIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfZF90cywgcHJlZGljdGVkID0gcHJlZF9vcmlnaW5hbF9zY2FsZSkNCg0KIyBQcmludCB0aGUgUk1TRQ0KY2F0KCJSTVNFIGZvciBEYWlseSBHR00gTW9kZWwgUHJlZGljdGlvbnMgKE9yaWdpbmFsIFNjYWxlKToiLCBybXNlX2dnbV9kLCAiXG4iKQ0KDQpgYGANCg0KIyMjIEhvbHQtV2ludGVycyBNb2RlbA0KDQpgYGB7cn0NCiMgYWRqdXN0IHRpbWVzZXJpZXMgdG8gZW5zdXJlIGRhdGUgY29uc2lzdGVuY3kNCnNhbGVzX21fdHMgPC0gdHMoc2FsZXNfbV90cywgZnJlcXVlbmN5PTEyLCBzdGFydD1jKDIwMjEsIDExKSkNCg0KaHcxX208LSBodyhzYWxlc19tX3RzLCBzZWFzb25hbD0iYWRkaXRpdmUiKQ0KaHcyX208LSBodyhzYWxlc19tX3RzLCBzZWFzb25hbD0ibXVsdGlwbGljYXRpdmUiKQ0KDQojIHByZWRpY3Rpb24NCmZpdHRlZF9odzEgPC0gaHcxX20kZml0dGVkDQpmaXR0ZWRfaHcyIDwtIGh3Ml9tJGZpdHRlZA0KDQpgYGANCg0KV2Ugbm93IHBsb3QgdGhlIG1vZGVscw0KDQpgYGB7cn0NCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBmb3IgZ2dwbG90DQpwbG90X2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgVGltZSA9IHRpbWUoc2FsZXNfbV90cyksDQogIEFjdHVhbCA9IGFzLm51bWVyaWMoc2FsZXNfbV90cyksDQogIEZpdHRlZF9BZGRpdGl2ZSA9IGFzLm51bWVyaWMoaHcxX20kZml0dGVkKSwNCiAgRml0dGVkX011bHRpcGxpY2F0aXZlID0gYXMubnVtZXJpYyhodzJfbSRmaXR0ZWQpDQopDQoNCiMgTWVsdCBkYXRhIGZvciBlYXNpZXIgZ2dwbG90IHVzYWdlDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KcGxvdF9kYXRhX21lbHRlZCA8LSBtZWx0KHBsb3RfZGF0YSwgaWQudmFycyA9ICJUaW1lIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJTZXJpZXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gIlZhbHVlIikNCg0KIyBQbG90IHVzaW5nIGdncGxvdDINCmdncGxvdChwbG90X2RhdGFfbWVsdGVkLCBhZXMoeCA9IFRpbWUsIHkgPSBWYWx1ZSwgY29sb3IgPSBTZXJpZXMpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChwbG90X2RhdGFfbWVsdGVkLCBTZXJpZXMgPT0gIkFjdHVhbCIpLCBzaXplID0gMikgKyAjIEFjdHVhbCB2YWx1ZXMgYXMgZG90cw0KICBnZW9tX2xpbmUoZGF0YSA9IHN1YnNldChwbG90X2RhdGFfbWVsdGVkLCBTZXJpZXMgIT0gIkFjdHVhbCIpLCBzaXplID0gMSkgKyAgIyBGaXR0ZWQgdmFsdWVzIGFzIGxpbmVzDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQWN0dWFsIHZzIEZpdHRlZCBWYWx1ZXMiLA0KICAgIHggPSAiVGltZSIsDQogICAgeSA9ICJWYWx1ZSIsDQogICAgY29sb3IgPSAiU2VyaWVzIg0KICApICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKA0KICAgIHZhbHVlcyA9IGMoIkFjdHVhbCIgPSAiYmxhY2siLCAiRml0dGVkX0FkZGl0aXZlIiA9ICJibHVlIiwgIkZpdHRlZF9NdWx0aXBsaWNhdGl2ZSIgPSAicmVkIiksDQogICAgbGFiZWxzID0gYygiQWN0dWFsIiwgIkZpdHRlZCAoQWRkaXRpdmUpIiwgIkZpdHRlZCAoTXVsdGlwbGljYXRpdmUpIikNCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKQ0KICApDQoNCmBgYA0KTG9va3MgbGlrZSB0aGUgbXVsdGlwbGljYXRpdmUgbW9kZWxzIGZvbGxvd3MgdGhlIGRhdGEgbW9yZSBtb3JlIGNsb3NlbHkgaW4gZ2VuZXJhbC4NCg0KYGBge3J9DQojIHJlc2lkdWFscw0KcmVzaWR1YWxzX2h3MSA8LSByZXNpZHVhbHMoaHcxX20pICANCnJlc2lkdWFsc19odzIgPC0gcmVzaWR1YWxzKGh3Ml9tKSAgDQp0c2Rpc3BsYXkocmVzaWR1YWxzX2h3MSkNCnRzZGlzcGxheShyZXNpZHVhbHNfaHcyKQ0KDQpgYGANCg0KYGBge3J9DQojIFN0YXRpb25hcml0eSBhbmQgQ29ycmVsYXRpb24NCiMgY2hlY2sgZm9yIHN0YXRpb25hcml0eSBvZiByZXNpZHVhbHMNCiMgYWRkaXRpdmUNCmFkZl90ZXN0IDwtIGFkZi50ZXN0KHJlc2lkdWFsc19odzEpICMgSDA6IHNlcmllcyBpcyBub24tc3RhdGlvbmFyeQ0KcHJpbnQoYWRmX3Rlc3QpICMgaWYgcC12YWwgPCBhbHBoYSwgc2VyaWVzIG5vdCBzdGF0aW9uYXJ5DQojIHNvIHdpdGggdGhpcyBtb2RlbCB3ZSBhY2hpZXZlIHN0YXRpb25hcnkgc2VyaWVzDQojIG11bHRpcGxpY2F0aXZlDQphZGZfdGVzdCA8LSBhZGYudGVzdChyZXNpZHVhbHNfaHcyKSAjIEgwOiBzZXJpZXMgaXMgbm9uLXN0YXRpb25hcnkNCnByaW50KGFkZl90ZXN0KSAjIGlmIHAtdmFsIDwgYWxwaGEsIHNlcmllcyBub3Qgc3RhdGlvbmFyeQ0KIyBzbyB3aXRoIHRoaXMgbW9kZWwgd2UgYWNoaWV2ZSBzdGF0aW9uYXJ5IHNlcmllcw0KDQojIGFkZGl0aXZlDQojIGNoZWNrIGZvciBhdXRvY29ycmVsYXRpb24gaW4gcmVzaWR1YWxzDQpCb3gudGVzdChyZXNpZHVhbHNfaHcxLCBsYWcgPSAxMCwgdHlwZSA9ICJManVuZy1Cb3giKSAjIGgwIHJlcyBpbmRlcA0KIyBwLXZhbCA+IGFscGhhID0+ICBEb250IHJlamVjdCBoMCwgc28gcmVzaWR1YWxzIGFyZSBpbmRlcA0KDQojIGFkZGl0aXZlDQojIGNoZWNrIGZvciBhdXRvY29ycmVsYXRpb24gaW4gcmVzaWR1YWxzDQpCb3gudGVzdChyZXNpZHVhbHNfaHcyLCBsYWcgPSAxMCwgdHlwZSA9ICJManVuZy1Cb3giKSAjIGgwIHJlcyBpbmRlcA0KIyBwLXZhbCA+IGFscGhhID0+ICBEb250IHJlamVjdCBoMCwgc28gcmVzaWR1YWxzIGFyZSBpbmRlcA0KDQpgYGANCk11bHRpcGxpY2F0aXZlIG1vZGVsIGZvbGxvd3MgdGhlIGRhdGEgYmV0dGVyIGFuZCBoYXMgc2xpZ2h0bHkgYmV0dGVyIHJlc2lkdWFscw0KDQpgYGB7cn0NCiMgZm9yZWNhc3QNCiMgc2F2ZSB0aGUgZm9yZWNhc3Qgb2YgdGhlIHNlY29uZCBtb2RlbA0KZm9yZWNhc3RfaHcxIDwtIGZvcmVjYXN0KGh3MV9tLCBoPTEyKQ0KZm9yZWNhc3RfaHcyIDwtIGZvcmVjYXN0KGh3Ml9tLCBoPTEyKQ0KDQojIEZvcmVjYXN0IHBsb3QNCiMgUGxvdCB0aGUgdGltZSBzZXJpZXMgd2l0aCBib3RoIGZvcmVjYXN0cw0KYXV0b3Bsb3Qoc2FsZXNfbV90cykgKw0KICBhdXRvbGF5ZXIoZm9yZWNhc3RfaHcxJG1lYW4sIHNlcmllcz0iQWRkaXRpdmUgSG9sdC1XaW50ZXJzIEZvcmVjYXN0IiwgUEk9RikgKw0KICBhdXRvbGF5ZXIoZm9yZWNhc3RfaHcyJG1lYW4sIHNlcmllcz0iTXVsdGlwbGljYXRpdmUgSG9sdC1XaW50ZXJzIEZvcmVjYXN0IiwgUEk9RikgKw0KICBnZ3RpdGxlKCJTYWxlcyBGb3JlY2FzdCB3aXRoIEhvbHQtV2ludGVycyBNb2RlbHMiKSArDQogIHhsYWIoIlRpbWUiKSArDQogIHlsYWIoIlNhbGVzIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoDQogICAgdmFsdWVzPWMoIkFkZGl0aXZlIEhvbHQtV2ludGVycyBGb3JlY2FzdCIgPSAiYmx1ZSIsDQogICAgICAgICAgICAgIk11bHRpcGxpY2F0aXZlIEhvbHQtV2ludGVycyBGb3JlY2FzdCIgPSAicmVkIikNCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQoNCmBgYA0KDQpgYGB7cn0NCiMgUk1TRSBDYWxjdWxhdGlvbiBmb3IgSG9sdC1XaW50ZXJzIG1vZGVscw0Kcm1zZV9odzEgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19tX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfaHcxKQ0Kcm1zZV9odzIgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19tX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfaHcyKQ0KDQojIFByaW50IFJNU0UgdmFsdWVzDQpjYXQoIlJNU0UgZm9yIEFkZGl0aXZlIEhvbHQtV2ludGVycyBNb2RlbDoiLCBybXNlX2h3MSwgIlxuIikNCmNhdCgiUk1TRSBmb3IgTXVsdGlwbGljYXRpdmUgSG9sdC1XaW50ZXJzIE1vZGVsOiIsIHJtc2VfaHcyLCAiXG4iKQ0KDQpgYGANCk11bHRpcGxpY2F0aXZlIG1vZGVsIGlzIGJldHRlcg0KDQpUaGUgSG9sdCB3aW50ZXJzIG1vZGVsIGhhcyBhIGZyZXF1ZW5jeSBsaW1pdCBvZiAyNCwgc28gd2UgY2Fubm90IGRvIGxhcmdlciB0aGFuIHRoYXQuIFdlZWtseSBhbmQgZGFpbHkgZGF0YSBoYXZlIDUyIGFuZCAzNjUgZnJlcXVlbmNpZXMgcmVzcGVjdGl2ZWx5IHNvIHdlIGNhbm5vdCBmaXQgdGhlIG1vZGVsIHdpdGggdGhlIFIgaW1wbGVtZW50YXRpb24gc28gZmFyLg0KDQoNCg0KIyMjIEFSSU1BIG1vZGVscw0KDQpBUklNQSBpcyBhIGFjcm9ueW0gZm9yIEF1dG8gUmVncmVzc2l2ZSBJbnRlZ3JhdGVkIE1vdmluZyBBdmVyYWdlLCBBUklNQQ0KKHAsZCxxKSB3aGVyZSBwIHJlZmVycyB0byB0aGUgQVIgcGFydCwgcSByZWZlcnMgdG8gdGhlIE1BIHBhcnQgYW5kIGQgaXMNCnRoZSBkZWdyZWUgb2YgZmlyc3QgZGlmZmVyZW5jZSBpbnZvbHZlZC4NCg0KDQpGaXJzdCB3ZSBud3dkIHRvIGNoZWNrIGlmIHRoZSBzZXJpZXMgaXMgc3RhdGlvbmFyeQ0KYGBge3J9DQojIHNlZSBpZiBzZXJpZXMgaXMgc3RhdGlvbmFyeQ0KYWRmLnRlc3Qoc2FsZXNfbV90cykgI0gwLCBzZXJpZXMgaXMgbm9uLXN0YXRpb25hcnkNCiMgcC12YWwgPiAwLjA1ID0+IGRvbnQgcmVqZWN0LCBub24gc3RhdGlvbmFyeTogc2VyaWVzIGlzIG5vdCBzdGF0aW9uYXJ5DQphZGYudGVzdChkaWZmKHNhbGVzX21fdHMpKSAjSDAsIHNlcmllcyBpcyBub24tc3RhdGlvbmFyeQ0KDQojIHNlZSB0aGUgYWNmIGFuZCBwYWNmDQp0c2Rpc3BsYXkoZGlmZihzYWxlc19tX3RzKSkNCg0KYGBgDQoNCiMjIyMgTW9udGhseSBzYWxlcw0KDQpgYGB7cn0NCnBsb3Qoc2FsZXNfbV90cykNCmBgYA0KDQpgYGB7cn0NCm5kaWZmcyhzYWxlc19tX3RzKQ0KDQpgYGANCg0KYGBge3J9DQp0c2Rpc3BsYXkoZGlmZihzYWxlc19tX3RzKSkNCmBgYA0KDQpDb3JyZWxvZ3JhbSBwbG90IG1heWJlIHN1Z2dlc3RzIEFSLTEgb3IgTUEtMSBhZnRlciBmaXJzdCBkaWZmZXJlbmNlDQoNCmBgYHtyfQ0KIyBBUklNQShwLGQscSkgPSAoMSwxLDApDQphcmltYTFfbTwtIEFyaW1hKHNhbGVzX21fdHMsIG9yZGVyPWMoMSwxLDApKQ0Kc3VtbWFyeShhcmltYTFfbSkNCg0KYGBgDQpgYGB7cn0NCiMgc3R1ZHkgcmVzaWR1YWwgdG8gc2VlIGlmIGlzIGEgZ29vZCBtb2RlbA0KcmVzaWQxX208LSByZXNpZHVhbHMoYXJpbWExX20pDQp0c2Rpc3BsYXkocmVzaWQxX20pDQpgYGANCg0KUmVzaWR1YWxzIGxvb2sgc3RhdGlvbmFyeSBhZnRlciBmaXR0aW5nIEFSSU1BDQoNCmBgYHtyfQ0KYXV0b19hcmltYV9tIDwtIGF1dG8uYXJpbWEoc2FsZXNfbV90cykNCmF1dG9fYXJpbWFfbQ0KDQphdXRvcGxvdChmb3JlY2FzdChhdXRvX2FyaW1hX20pKQ0KY2hlY2tyZXNpZHVhbHMoYXV0b19hcmltYV9tKQ0KYGBgDQoNClRoZSByZXNpZHVhbHMgb2YgdGhlIEF1dG9hcmltYSBsb29rIHN0YXRpb25hcnkNCg0KQUlDIG9mIHRoZSB0aGUgbWFudWFsIGFyaW1hIGlzIDEyNjUsIHdoaWxlIHRoZSBvbmUgb2YgdGhlIGF1dG9hcmltYSBpcyAxMjYzLiBMZXRzIHVzZSB0aGUgYXV0b2FyaW1hDQoNCmBgYHtyfQ0KIyBGaXR0ZWQgdmFsdWVzIGZyb20gYm90aCBtb2RlbHMNCmZpdHRlZF9hdXRvX2FyaW1hIDwtIGZpdHRlZChhdXRvX2FyaW1hX20pDQpmaXR0ZWRfYXJpbWExIDwtIGZpdHRlZChhcmltYTFfbSkNCg0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciBwbG90dGluZw0KcGxvdF9kYXRhIDwtIGRhdGEuZnJhbWUoDQogIFRpbWUgPSB0aW1lKHNhbGVzX21fdHMpLA0KICBBY3R1YWwgPSBhcy5udW1lcmljKHNhbGVzX21fdHMpLA0KICBGaXR0ZWRfQXV0b19BUklNQSA9IGFzLm51bWVyaWMoZml0dGVkX2F1dG9fYXJpbWEpLA0KICBGaXR0ZWRfQVJJTUExID0gYXMubnVtZXJpYyhmaXR0ZWRfYXJpbWExKQ0KKQ0KDQojIE1lbHQgdGhlIGRhdGEgZnJhbWUNCnBsb3RfZGF0YV9tZWx0ZWQgPC0gbWVsdChwbG90X2RhdGEsIGlkLnZhcnMgPSAiVGltZSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU2VyaWVzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJWYWx1ZSIpDQoNCiMgUGxvdA0KDQpnZ3Bsb3QocGxvdF9kYXRhX21lbHRlZCwgYWVzKHggPSBUaW1lLCB5ID0gVmFsdWUsIGNvbG9yID0gU2VyaWVzKSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBzdWJzZXQocGxvdF9kYXRhX21lbHRlZCwgU2VyaWVzID09ICJBY3R1YWwiKSwgc2l6ZSA9IDIpICsgICMgQWN0dWFsIHZhbHVlcyBhcyBwb2ludHMNCiAgZ2VvbV9saW5lKGRhdGEgPSBzdWJzZXQocGxvdF9kYXRhX21lbHRlZCwgU2VyaWVzICE9ICJBY3R1YWwiKSwgc2l6ZSA9IDEpICsgICAjIEZpdHRlZCB2YWx1ZXMgYXMgbGluZXMNCiAgbGFicygNCiAgICB0aXRsZSA9ICJBY3R1YWwgdnMgRml0dGVkIFZhbHVlcyBmb3IgQVJJTUEgTW9kZWxzIiwNCiAgICB4ID0gIlRpbWUiLA0KICAgIHkgPSAiU2FsZXMiLA0KICAgIGNvbG9yID0gIlNlcmllcyINCiAgKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKCJBY3R1YWwiID0gImJsYWNrIiwgIkZpdHRlZF9BdXRvX0FSSU1BIiA9ICJibHVlIiwgIkZpdHRlZF9BUklNQTEiID0gInJlZCIpLA0KICAgIGxhYmVscyA9IGMoIkFjdHVhbCIsICJGaXR0ZWQgKEF1dG8gQVJJTUEpIiwgIkZpdHRlZCAoQVJJTUEoMSwxLDApKSIpDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgUk1TRSBmb3IgdGhlIGZpdHRlZCB2YWx1ZXMNCiMgQ2FsY3VsYXRlIFJNU0UgZm9yIGVhY2ggbW9kZWwNCnJtc2VfYXV0b19hcmltYSA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX21fdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9hdXRvX2FyaW1hKQ0Kcm1zZV9hcmltYTEgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19tX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfYXJpbWExKQ0KDQojIFByaW50IFJNU0UgdmFsdWVzDQpjYXQoIlJNU0UgZm9yIEF1dG8gQVJJTUEgTW9kZWw6Iiwgcm1zZV9hdXRvX2FyaW1hLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBBUklNQSgxLDEsMCkgTW9kZWw6Iiwgcm1zZV9hcmltYTEsICJcbiIpDQoNCg0KYGBgDQpUaGUgUk1TRSBvZiB0aGUgQXV0b2FyaW1hIGlzIGJldHRlciBhcyBpcyB0aGUgQUlDLg0KDQpUaGUgQVJJTUEoMCwxLDEpIG1vZGVsIGNhbiBiZSBkZXNjcmliZWQgc2ltcGx5IGFzIGEgKipyYW5kb20gd2FsayB3aXRoDQpkcmlmdCoqLiBIZXJlJ3Mgd2hhdCB0aGF0IG1lYW5zOg0KDQoxLiAgKipBUiAoQXV0b1JlZ3Jlc3NpdmUpIFBhcnQ6KioNCg0KICAgIC0gICBUaGUgZmlyc3QgbnVtYmVyLCAqKjAqKiwgaW5kaWNhdGVzIHRoZSBvcmRlciBvZiB0aGUNCiAgICAgICAgYXV0b3JlZ3Jlc3NpdmUgcGFydC4gSW4gdGhpcyBjYXNlLCBpdCBtZWFucyB0aGVyZSBhcmUgbm8NCiAgICAgICAgYXV0b3JlZ3Jlc3NpdmUgdGVybXMgKGkuZS4sIHRoZSBtb2RlbCBkb2VzIG5vdCB1c2UgcGFzdCB2YWx1ZXMNCiAgICAgICAgb2YgdGhlIHNlcmllcyB0byBwcmVkaWN0IGZ1dHVyZSB2YWx1ZXMpLg0KDQoyLiAgKipJIChJbnRlZ3JhdGVkKSBQYXJ0OioqDQoNCiAgICAtICAgVGhlIHNlY29uZCBudW1iZXIsICoqMSoqLCBpbmRpY2F0ZXMgdGhlIGRlZ3JlZSBvZiBkaWZmZXJlbmNpbmcNCiAgICAgICAgcmVxdWlyZWQgdG8gbWFrZSB0aGUgdGltZSBzZXJpZXMgc3RhdGlvbmFyeS4gRGlmZmVyZW5jaW5nIGlzIGENCiAgICAgICAgdGVjaG5pcXVlIHVzZWQgdG8gcmVtb3ZlIHRyZW5kcyBhbmQgc2Vhc29uYWxpdHkgZnJvbSB0aGUgc2VyaWVzLg0KICAgICAgICBBIHZhbHVlIG9mIDEgbWVhbnMgdGhlIHNlcmllcyBpcyBkaWZmZXJlbmNlZCBvbmNlLg0KDQozLiAgKipNQSAoTW92aW5nIEF2ZXJhZ2UpIFBhcnQ6KioNCg0KICAgIC0gICBUaGUgdGhpcmQgbnVtYmVyLCAqKjEqKiwgaW5kaWNhdGVzIHRoZSBvcmRlciBvZiB0aGUgbW92aW5nDQogICAgICAgIGF2ZXJhZ2UgcGFydC4gDQoNCkFuIEFSSU1BKDAsMSwxKSBtb2RlbCBpcyBzdWl0YWJsZSB3aGVuOg0KDQpUaGUgZD0xIHBhcmFtZXRlciBpbiBBUklNQSgwLDEsMSkgaW5kaWNhdGVzIHRoYXQgdGhlIHNlcmllcyBpcyBkaWZmZXJlbmNlZCBvbmNlIHRvIGFjaGlldmUgc3RhdGlvbmFyaXR5Lg0KQmVmb3JlIGRpZmZlcmVuY2luZywgdGhlIHNlcmllcyBtYXkgZXhoaWJpdCBhIGxpbmVhciB0cmVuZCBvciByYW5kb20gd2FsayBiZWhhdmlvci4NCkFmdGVyIGRpZmZlcmVuY2luZywgdGhlIHNlcmllcyBzaG91bGQgc2hvdyBubyB0cmVuZCBhbmQgaGF2ZSByZWxhdGl2ZWx5IHN0YWJsZSBtZWFuIGFuZCB2YXJpYW5jZQ0KDQpUaGUgcT0xIGluIEFSSU1BKDAsMSwxKSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VyaWVzIGlzIG1vZGVsZWQgd2l0aCBhIGZpcnN0LW9yZGVyIG1vdmluZyBhdmVyYWdlIGNvbXBvbmVudCBhZnRlciBkaWZmZXJlbmNpbmcuDQpUaGUgYXV0b2NvcnJlbGF0aW9uIGZ1bmN0aW9uIChBQ0YpIG9mIHRoZSBkaWZmZXJlbmNlZCBzZXJpZXMgc2hvdWxkIHNob3c6DQpBIHNpZ25pZmljYW50IHNwaWtlIGF0IGxhZyAxLg0KUmFwaWQgZGVjYXkgdG8gemVybyBhZnRlciBsYWcgMS4NClRoZSBwYXJ0aWFsIGF1dG9jb3JyZWxhdGlvbiBmdW5jdGlvbiAoUEFDRikgc2hvdWxkIHNob3cgbm8gc2lnbmlmaWNhbnQgbGFncy4NCg0KDQpgYGB7cn0NCiMgc3R1ZHkgcmVzaWR1YWwgdG8gc2VlIGlmIGlzIGEgZ29vZCBtb2RlbA0KcmVzaWRfYXV0b2FyaW1hX208LSByZXNpZHVhbHMoYXV0b19hcmltYV9tKQ0KdHNkaXNwbGF5KHJlc2lkX2F1dG9hcmltYV9tKQ0KYGBgDQoNCiMjIyMgV2Vla2x5IHNhbGVzDQoNCg0KDQpgYGB7cn0NCiMgc2VlIGlmIHNlcmllcyBpcyBzdGF0aW9uYXJ5DQphZGYudGVzdChzYWxlc193X3RzKSAjSDAsIHNlcmllcyBpcyBub24tc3RhdGlvbmFyeQ0KIyBwLXZhbCA+IDAuMDUgPT4gZG9udCByZWplY3QsIG5vbiBzdGF0aW9uYXJ5OiBzZXJpZXMgaXMgbm90IHN0YXRpb25hcnkNCmFkZi50ZXN0KGRpZmYoc2FsZXNfd190cykpICMgYWZ0ZXIgZGlmZiBpcyBzYXRpb25hcnkNCmBgYA0KQWZ0ZXIgZGlmZmVyZW5jaW5nLCBsb29rcyBzdGF0aW9uYXJ5DQoNCmBgYHtyfQ0KdHNkaXNwbGF5KGRpZmYoc2FsZXNfd190cykpDQpgYGANCg0KQ29ycmVsb2dyYW1zIHN1Z2dlc3QgbWF5YmUgQVIgMSBvciBNQSAxLg0KDQpgYGB7cn0NCiMjIyBNYW51YWwgQVJJTUEtLS0tLS0tLS0tLS0NCiMgQVJJTUEocCxkLHEpID0gKDEsMSwwKQ0KYXJpbWExX3c8LSBBcmltYShzYWxlc193X3RzLCBvcmRlcj1jKDEsMSwwKSkNCnN1bW1hcnkoYXJpbWExX3cpDQoNCmBgYA0KDQpgYGB7cn0NCmF1dG9fYXJpbWFfdyA8LSBhdXRvLmFyaW1hKHNhbGVzX3dfdHMpDQpzdW1tYXJ5KGF1dG9fYXJpbWFfdykNCmBgYA0KDQpBSUMgb24gdGhlIEF1dG9hcmltYSBpcyBiZXR0ZXIsIGxldHMgZ28gd2l0aCB0aGF0IG9uZQ0KDQpgYGB7cn0NCmNoZWNrcmVzaWR1YWxzKGF1dG9fYXJpbWFfdykNCmBgYA0KUmVzaWR1YWxzIGxvb2sgc3RhdGlvbmFyeSwgc2VlIHRoZSBwbG90cyBmb3IgYm90aCBtb2RlbHMNCg0KYGBge3J9DQojIEZpdCBBUklNQSBtb2RlbHMgZm9yIHdlZWtseSBkYXRhDQphcmltYTFfdyA8LSBBcmltYShzYWxlc193X3RzLCBvcmRlciA9IGMoMSwgMSwgMCkpDQphdXRvX2FyaW1hX3cgPC0gYXV0by5hcmltYShzYWxlc193X3RzKQ0KDQojIEV4dHJhY3QgZml0dGVkIHZhbHVlcyBmb3IgYm90aCBtb2RlbHMNCmZpdHRlZF9hcmltYTFfdyA8LSBmaXR0ZWQoYXJpbWExX3cpDQpmaXR0ZWRfYXV0b19hcmltYV93IDwtIGZpdHRlZChhdXRvX2FyaW1hX3cpDQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBmb3IgcGxvdHRpbmcNCnBsb3RfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBUaW1lID0gdGltZShzYWxlc193X3RzKSwNCiAgQWN0dWFsID0gYXMubnVtZXJpYyhzYWxlc193X3RzKSwNCiAgRml0dGVkX0FSSU1BMSA9IGFzLm51bWVyaWMoZml0dGVkX2FyaW1hMV93KSwNCiAgRml0dGVkX0F1dG9fQVJJTUEgPSBhcy5udW1lcmljKGZpdHRlZF9hdXRvX2FyaW1hX3cpDQopDQoNCiMgTWVsdCB0aGUgZGF0YSBmcmFtZSBmb3IgZ2dwbG90Mg0KcGxvdF9kYXRhX21lbHRlZCA8LSBtZWx0KHBsb3RfZGF0YSwgaWQudmFycyA9ICJUaW1lIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJTZXJpZXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gIlZhbHVlIikNCg0KIyBQbG90IHVzaW5nIGdncGxvdDINCmdncGxvdChwbG90X2RhdGFfbWVsdGVkLCBhZXMoeCA9IFRpbWUsIHkgPSBWYWx1ZSwgY29sb3IgPSBTZXJpZXMpKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChwbG90X2RhdGFfbWVsdGVkLCBTZXJpZXMgPT0gIkFjdHVhbCIpLCBzaXplID0gMikgKyAgIyBBY3R1YWwgdmFsdWVzIGFzIHBvaW50cw0KICBnZW9tX2xpbmUoZGF0YSA9IHN1YnNldChwbG90X2RhdGFfbWVsdGVkLCBTZXJpZXMgIT0gIkFjdHVhbCIpLCBzaXplID0gMSkgKyAgICMgRml0dGVkIHZhbHVlcyBhcyBsaW5lcw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkFjdHVhbCB2cyBGaXR0ZWQgVmFsdWVzIGZvciBBUklNQSBNb2RlbHMgKFdlZWtseSkiLA0KICAgIHggPSAiVGltZSIsDQogICAgeSA9ICJTYWxlcyIsDQogICAgY29sb3IgPSAiU2VyaWVzIg0KICApICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKA0KICAgIHZhbHVlcyA9IGMoIkFjdHVhbCIgPSAiYmxhY2siLCAiRml0dGVkX0FSSU1BMSIgPSAicmVkIiwgIkZpdHRlZF9BdXRvX0FSSU1BIiA9ICJibHVlIiksDQogICAgbGFiZWxzID0gYygiQWN0dWFsIiwgIkZpdHRlZCAoQVJJTUEoMSwxLDApKSIsICJGaXR0ZWQgKEF1dG8gQVJJTUEpIikNCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKQ0KICApDQpgYGANCg0KYGBge3J9DQojIENhbGN1bGF0ZSBSTVNFIGZvciBib3RoIG1vZGVscw0Kcm1zZV9hcmltYTFfdyA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX3dfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9hcmltYTFfdykNCnJtc2VfYXV0b19hcmltYV93IDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfd190cywgcHJlZGljdGVkID0gZml0dGVkX2F1dG9fYXJpbWFfdykNCg0KIyBQcmludCBSTVNFIHZhbHVlcw0KY2F0KCJSTVNFIGZvciBBUklNQSgxLDEsMCkgTW9kZWwgKFdlZWtseSk6Iiwgcm1zZV9hcmltYTFfdywgIlxuIikNCmNhdCgiUk1TRSBmb3IgQXV0byBBUklNQSBNb2RlbCAoV2Vla2x5KToiLCBybXNlX2F1dG9fYXJpbWFfdywgIlxuIikNCmBgYA0KVGhlIEF1dG8tYXJpbWEgaXMgYWxzbyBiZXR0ZXIgaW4gdGVybXMgb2YgUk1TRQ0KDQoNCiMjIyMgRGFpbHkgc2FsZXMNCg0KDQpgYGB7cn0NCiMgc2VlIGlmIHNlcmllcyBpcyBzdGF0aW9uYXJ5DQphZGYudGVzdChzYWxlc19kX3RzKSAjSDAsIHNlcmllcyBpcyBub24tc3RhdGlvbmFyeQ0KIyBwLXZhbCA8IDAuMDUgPT4gIHJlamVjdCBub24gc3RhdGlvbmFyeTogc2VyaWVzIG1pZ2h0IGJlIHN0YXRpb25hcnkNCg0KYGBgDQpObyBuZWVkIGZvciBkaWZmZXJlbmNpbmcgYmVjYXVzZSBpcyBhbHJlYWR5IHN0YXRpb25hcnksIHRyeSB0byBtb2RlbCB3aXRoIGFyaW1hDQoNCmBgYHtyfQ0KdHNkaXNwbGF5KHNhbGVzX2RfdHMpDQpgYGANCg0KDQpBdXRvY29ycmVsb2dyYW1zIGFyZSBub3QgZWFzeSB0byBpbnRlcnByZXQsIGJ1dCBsZXRzIHRyeSB3aXRoIGEgYmFzZWxpbmUgbW9kZWwNCg0KYGBge3J9DQojIEFSSU1BKHAsZCxxKSA9ICgyLDEsMCkNCmFyaW1hMV9kPC0gQXJpbWEoc2FsZXNfZF90cywgb3JkZXI9YygxLDAsMSkpDQpzdW1tYXJ5KGFyaW1hMV9kKQ0KDQpgYGANCmBgYHtyfQ0KY2hlY2tyZXNpZHVhbHMoYXJpbWExX2QpDQpgYGANCg0KUmVzaWR1YWxzIGxvb2sgbm90IGVudGlyZWx5IHN0YXRpb25hcnkNCg0KVHJ5IHRvIG1vZGVsIHdpdGggYXV0b21hdGljIGFwcHJvYWNoOg0KDQpgYGB7cn0NCmF1dG9fYXJpbWFfZCA8LSBhdXRvLmFyaW1hKHNhbGVzX2RfdHMpDQpzdW1tYXJ5KGF1dG9fYXJpbWFfZCkNCmBgYA0KDQoNCmBgYHtyfQ0KY2hlY2tyZXNpZHVhbHMoYXV0b19hcmltYV9kKQ0KYGBgDQoNClJyZXNpZHVhbHMgaW1wcm92ZSwgYW5kIEFJQyBpcyBsb3dlciBpbiB0aGUgYXV0b2FyaW1hDQpDaGVjayB0aGUgZml0IGZvciBib3RoIG1vZGVscw0KDQpgYGB7cn0NCiMgRXh0cmFjdCBmaXR0ZWQgdmFsdWVzIGZvciBib3RoIG1vZGVscw0KZml0dGVkX2FyaW1hMV9kIDwtIGZpdHRlZChhcmltYTFfZCkNCmZpdHRlZF9hdXRvX2FyaW1hX2QgPC0gZml0dGVkKGF1dG9fYXJpbWFfZCkNCg0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciBwbG90dGluZw0KcGxvdF9kYXRhIDwtIGRhdGEuZnJhbWUoDQogIFRpbWUgPSB0aW1lKHNhbGVzX2RfdHMpLA0KICBBY3R1YWwgPSBhcy5udW1lcmljKHNhbGVzX2RfdHMpLA0KICBGaXR0ZWRfQVJJTUExID0gYXMubnVtZXJpYyhmaXR0ZWRfYXJpbWExX2QpLA0KICBGaXR0ZWRfQXV0b19BUklNQSA9IGFzLm51bWVyaWMoZml0dGVkX2F1dG9fYXJpbWFfZCkNCikNCg0KIyBNZWx0IHRoZSBkYXRhIGZyYW1lIGZvciBnZ3Bsb3QyDQpwbG90X2RhdGFfbWVsdGVkIDwtIG1lbHQocGxvdF9kYXRhLCBpZC52YXJzID0gIlRpbWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNlcmllcyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiVmFsdWUiKQ0KDQojIFBsb3QgdXNpbmcgZ2dwbG90Mg0KZ2dwbG90KHBsb3RfZGF0YV9tZWx0ZWQsIGFlcyh4ID0gVGltZSwgeSA9IFZhbHVlLCBjb2xvciA9IFNlcmllcykpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gc3Vic2V0KHBsb3RfZGF0YV9tZWx0ZWQsIFNlcmllcyA9PSAiQWN0dWFsIiksIHNpemUgPSAyKSArICAjIEFjdHVhbCB2YWx1ZXMgYXMgcG9pbnRzDQogIGdlb21fbGluZShkYXRhID0gc3Vic2V0KHBsb3RfZGF0YV9tZWx0ZWQsIFNlcmllcyAhPSAiQWN0dWFsIiksIHNpemUgPSAxKSArICAgIyBGaXR0ZWQgdmFsdWVzIGFzIGxpbmVzDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQWN0dWFsIHZzIEZpdHRlZCBWYWx1ZXMgZm9yIEFSSU1BIE1vZGVscyAoRGFpbHkpIiwNCiAgICB4ID0gIlRpbWUiLA0KICAgIHkgPSAiU2FsZXMiLA0KICAgIGNvbG9yID0gIlNlcmllcyINCiAgKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKCJBY3R1YWwiID0gImJsYWNrIiwgIkZpdHRlZF9BUklNQTEiID0gInJlZCIsICJGaXR0ZWRfQXV0b19BUklNQSIgPSAiYmx1ZSIpLA0KICAgIGxhYmVscyA9IGMoIkFjdHVhbCIsICJGaXR0ZWQgKEFSSU1BKDEsMCwxKSkiLCAiRml0dGVkIChBdXRvIEFSSU1BKSIpDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KYGBgDQoNClBsb3QgaXMgbm90IHJlYWRhYmxlLCBidXQgY2hlY2sgdGhlIFJNU0UgZm9yIGJvdGggbW9kZWxzIHRvIGNvbmZpcm0gd2loY2ggZml0cyBiZXR0ZXINCg0KYGBge3J9DQojIENhbGN1bGF0ZSBSTVNFIGZvciBib3RoIG1vZGVscw0Kcm1zZV9hcmltYTFfZCA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX2RfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9hcmltYTFfZCkNCnJtc2VfYXV0b19hcmltYV9kIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfZF90cywgcHJlZGljdGVkID0gZml0dGVkX2F1dG9fYXJpbWFfZCkNCg0KIyBQcmludCBSTVNFIHZhbHVlcw0KY2F0KCJSTVNFIGZvciBBUklNQSgxLDAsMSkgTW9kZWwgKERhaWx5KToiLCBybXNlX2FyaW1hMV9kLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBBdXRvIEFSSU1BIE1vZGVsIChEYWlseSk6Iiwgcm1zZV9hdXRvX2FyaW1hX2QsICJcbiIpDQpgYGANCkF1dG9hcmltYSBpcyBtdWNoIGJldHRlciwgbm93IHRyeSB0byBpbXByb3ZlIHdpdGggc2Vhc29uYWxpdHksIGJlYWN1c2UgZGFpbHkgZGF0YSBsb29rcyBzZWFzb25hbCBlYWNoIDcgZGF5cy4NCg0KIyMjIFNBUklNQQ0KYGBge3J9DQojIERhaWx5IHNhbGVzDQp0c2Rpc3BsYXkoc2FsZXNfZF90cykgIyANCnRzZGlzcGxheShkaWZmKHNhbGVzX2RfdHMpKQ0KYGBgDQoNCmBgYHtyfQ0Kc2FyaW1hX2QgPC0gYXV0by5hcmltYShzYWxlc19kX3RzLCBzZWFzb25hbD1UUlVFKQ0Kc3VtbWFyeShzYXJpbWFfZCkNCmBgYA0KYGBge3J9DQpyZXNpZF9kczwtIHJlc2lkdWFscyhzYXJpbWFfZCkNCnRzZGlzcGxheShyZXNpZF9kcykNCg0KIyBjaGVjayBmb3IgYXV0b2NvcnJlbGF0aW9uDQpCb3gudGVzdChyZXNpZHVhbHMoc2FyaW1hX2QpLCB0eXBlPSJManVuZy1Cb3giKQ0KIyBBIGxvdyBwLXZhbHVlICg8MC4wNSkgc3VnZ2VzdHMgcmVzaWR1YWwgYXV0b2NvcnJlbGF0aW9uLg0KYGBgDQoNCg0KTG9va3MgbGlrZSBBYXJpbWEgaXMgdGhlIHNhbWUgaW4gdGVybXMgb2YgQUlDLCBsZXRzIGNoZWNrIHRoZSBSTVNFOg0KDQpgYGB7cn0NCiMgRXh0cmFjdCBmaXR0ZWQgdmFsdWVzIGZvciBib3RoIG1vZGVscw0KDQpmaXR0ZWRfc2FyaW1hX2QgPC0gZml0dGVkKHNhcmltYV9kKQ0KDQojIENhbGN1bGF0ZSBSTVNFIGZvciBib3RoIG1vZGVscw0Kcm1zZV9zYXJpbWFfZCA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX2RfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9zYXJpbWFfZCkNCg0KIyBQcmludCBSTVNFIHZhbHVlcw0KY2F0KCJSTVNFIGZvciBBdXRvIEFSSU1BIE1vZGVsIChEYWlseSk6Iiwgcm1zZV9hdXRvX2FyaW1hX2QsICJcbiIpDQpjYXQoIlJNU0UgZm9yIFNlYXNvbmFsIEFSSU1BIE1vZGVsIChEYWlseSk6Iiwgcm1zZV9zYXJpbWFfZCwgIlxuIikNCg0KYGBgDQpUaGUgUk1TRSBpcyBleGFjdGx5IHRoZSBzYW1lLCB0aGV5IGFyZSB0aGUgc2FtZSBtb2RlbC4NCg0KIyMjIFNBUklNQVgNClJlZmluZSBTQVJJTUEgd2l0aCBleHRlcm5hbCByZWdyZXNzb3JzDQpgYGB7cn0NCiMgcmVhZGVmaW5lIHNhbGVzX2RfdHMNCmhlYWQoZGZfbWVyZ2VkX2QpDQpzYWxlc19kX3RzIDwtIHRzKGV4cChkZl9tZXJnZWRfZCRzYWxlc19jb3ApLCBmcmVxdWVuY3k9MzY1LCBzdGFydD1jKDIwMjEsIDMzNCkpICAjIDMzNCBpcyBOb3ZlbWJlciAzMA0Kc2Vhc29uYWxfc2FsZXNfZF90cyA8LSB0cyhleHAoZGZfbWVyZ2VkX2Qkc2FsZXNfY29wKSwgZnJlcXVlbmN5PTcsIHN0YXJ0PWMoMjAyMSwgMzM0KSkgICMgMzM0IGlzIE5vdmVtYmVyIDMwDQpwbG90KHNhbGVzX2RfdHMpDQp0c2Rpc3BsYXkoc2FsZXNfZF90cyxsYWcubWF4ID0gMzApDQp0c2Rpc3BsYXkoc2Vhc29uYWxfc2FsZXNfZF90cyxsYWcubWF4ID0gMzApDQojIGRlZmluZSByZWdyZXNvcnMNCiMgU2VsZWN0IHNwZWNpZmljIGNvbHVtbnMgYnkgbmFtZQ0KeF9yZWdyZXNzb3JzX2QgPC0gZGZfbWVyZ2VkX2QgJT4lIHNlbGVjdChyYWluX3N1bSwgZngsIHRtZWRpYW4pDQojIEFwcGx5IHRoZSBleHBvbmVudGlhbCBmdW5jdGlvbiB0byBlYWNoIGNvbHVtbg0KeF9yZWdyZXNzb3JzX2QgPC0gYXMuZGF0YS5mcmFtZShhcHBseSh4X3JlZ3Jlc3NvcnNfZCwgMiwgZXhwKSkNCiMgQ29udmVydCB0byBhIG1hdHJpeCBmb3IgQVJJTUEgbW9kZWxpbmcNCnhfcmVncmVzc29yc19kIDwtIGFzLm1hdHJpeCh4X3JlZ3Jlc3NvcnNfZCkNCg0KYGBgDQoNCg0KDQpgYGB7cn0NCiMgZml0IHRoZSBtb2RlbCBvbiBzYWxlcw0KIyBGaXQgYW4gYXV0by5hcmltYSBtb2RlbCB3aXRoIHNlYXNvbmFsIGNvbXBvbmVudCBhbmQgZXh0ZXJuYWwgcmVncmVzc29ycw0Kc2FyaW1heF9tb2RlbF9kIDwtIGF1dG8uYXJpbWEoDQogIHNhbGVzX2RfdHMsDQogIHNlYXNvbmFsID0gVFJVRSwgICAgICAgICAgICAgICAjIEVuYWJsZSBzZWFzb25hbCBjb21wb25lbnRzDQogIHhyZWcgPSB4X3JlZ3Jlc3NvcnNfZCAgICAgICAgICAjIEV4dGVybmFsIHJlZ3Jlc3NvcnMNCikNCg0KIyBEaXNwbGF5IHRoZSBzdW1tYXJ5IG9mIHRoZSBmaXR0ZWQgbW9kZWwNCnN1bW1hcnkoc2FyaW1heF9tb2RlbF9kKQ0KDQpgYGANClRoZSBBSUMgYWN0dWFsbHkgZGVjcmVhc2VzLCBsZXRzIGNoZWNrIHRoZSBSTVNFDQoNCmBgYHtyfQ0KIyBFeHRyYWN0IGZpdHRlZCB2YWx1ZXMgZm9yIGFsbCBtb2RlbHMNCmZpdHRlZF9zYXJpbWF4X2QgPC0gZml0dGVkKHNhcmltYXhfbW9kZWxfZCkNCg0KIyBDYWxjdWxhdGUgUk1TRSBmb3IgYWxsIG1vZGVscw0Kcm1zZV9zYXJpbWF4X2QgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19kX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfc2FyaW1heF9kKQ0KDQojIFByaW50IFJNU0UgdmFsdWVzDQpjYXQoIlJNU0UgZm9yIEF1dG8gQVJJTUEgTW9kZWwgKERhaWx5KToiLCBybXNlX2F1dG9fYXJpbWFfZCwgIlxuIikNCmNhdCgiUk1TRSBmb3IgU2Vhc29uYWwgQVJJTUEgTW9kZWwgKERhaWx5KToiLCBybXNlX3NhcmltYV9kLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBTQVJJTUFYIE1vZGVsIChEYWlseSk6Iiwgcm1zZV9zYXJpbWF4X2QsICJcbiIpDQoNCmBgYA0KVGhlIFJNU0UgYWxzbyB3b3JzZW5zLCBzbyBzdGF5IHdpdGggcmVndWxhciBBdXRvLUFSSU1BDQoNCiMjIyBFeHBvbmVudGlhbCBTbW9vdGhpbmcgbWV0aG9kcw0KDQojIyMjIFNpbXBsZSBFeHBvbmVudGlhbCBTbW9vdGhpbmcNCg0KIyMjIyMgTW9udGhseSBTYWxlcw0KDQpNb250aGx5IFNhbGVzDQoNCmBgYHtyfQ0KZml0X20xIDwtIHNlcyhzYWxlc19tX3RzLCBhbHBoYSA9IDAuMiwgaW5pdGlhbCA9ICdzaW1wbGUnLCBoPTUpDQpmaXRfbTIgPC0gc2VzKHNhbGVzX21fdHMsIGFscGhhID0gMC42LCBpbml0aWFsID0gJ3NpbXBsZScsIGg9NSkNCmZpdF9tMyA8LSBzZXMoc2FsZXNfbV90cywgaD01KQ0KDQpwbG90KHNhbGVzX21fdHMsIHlsYWI9J01vbnRobHkgU2FsZXMnLCB4bGFiPSdNb250aHMnKQ0KbGluZXMoZml0dGVkKGZpdF9tMSksIGNvbD0nYmx1ZScsIHR5cGU9J28nKQ0KbGluZXMoZml0dGVkKGZpdF9tMiksIGNvbD0ncmVkJywgdHlwZT0nbycpDQpsaW5lcyhmaXR0ZWQoZml0X20zKSwgY29sPSdncmVlbicsIHR5cGU9J28nKQ0KYGBgDQoNCmBgYHtyfQ0KZm9yZWNhc3RfbTEgPC0gc2VzKHNhbGVzX21fdHMsIGg9NSkNCg0KIyBBY2N1cmFjeSBvZiBvbmUtc3RlcC1haGVhZCB0cmFpbmluZyBlcnJvcnMNCnJvdW5kKGFjY3VyYWN5KGZvcmVjYXN0X20xKSwyKQ0KDQpzdW1tYXJ5KGZvcmVjYXN0X20xKQ0KDQphdXRvcGxvdChmb3JlY2FzdF9tMSkgKyBhdXRvbGF5ZXIoZml0dGVkKGZvcmVjYXN0X20xKSxzZXJpZXM9J0ZpdHRlZCcpICsgeWxhYigiTW9udGhseSBTYWxlcyIpK3hsYWIoIk1vbnRocyIpDQpgYGANCg0KYGBge3J9DQojIEV4dHJhY3QgZml0dGVkIHZhbHVlcyBmb3IgZWFjaCBtb2RlbA0KZml0dGVkX20xIDwtIGZpdHRlZChmaXRfbTEpDQpmaXR0ZWRfbTIgPC0gZml0dGVkKGZpdF9tMikNCmZpdHRlZF9tMyA8LSBmaXR0ZWQoZml0X20zKQ0KDQojIENhbGN1bGF0ZSBSTVNFIGZvciBlYWNoIG1vZGVsDQpybXNlX20xIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfbV90cywgcHJlZGljdGVkID0gZml0dGVkX20xKQ0Kcm1zZV9tMiA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX21fdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9tMikNCnJtc2VfbTMgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19tX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfbTMpDQoNCiMgUHJpbnQgUk1TRSB2YWx1ZXMNCmNhdCgiUk1TRSBmb3IgU0VTIE1vZGVsIDEgKGFscGhhID0gMC4yKToiLCBybXNlX20xLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBTRVMgTW9kZWwgMiAoYWxwaGEgPSAwLjYpOiIsIHJtc2VfbTIsICJcbiIpDQpjYXQoIlJNU0UgZm9yIFNFUyBNb2RlbCAzIChPcHRpbWl6ZWQgYWxwaGEpOiIsIHJtc2VfbTMsICJcbiIpDQoNCmBgYA0KYGBge3J9DQpybXNlX2V4cF9zbV9tIDwtIHJtc2VfbTINCmBgYA0KDQojIyMjIyBXZWVrbHkgU2FsZXMNCg0KV2Vla2x5IFNhbGVzDQoNCkZvciB3ZWVrbHkgZGF0YSwgZXhwb25lbnRpYWwgc21vb3RoaW5nIGNhbiBjYXB0dXJlIGxvbmdlci10ZXJtIHRyZW5kcw0KYW5kIHNlYXNvbmFsIHBhdHRlcm5zIHRoYXQgcmVwZWF0IG9uIGEgd2Vla2x5IGJhc2lzLiBXZWVrbHkgZGF0YSBjYW4NCmFsc28gaGF2ZSBzZWFzb25hbCBjb21wb25lbnRzIHJlbGF0ZWQgdG8gbW9udGhzLCBxdWFydGVycywgb3IgeWVhcnMuDQoNCg0KDQpgYGB7cn0NCmZpdF93MSA8LSBzZXMoc2FsZXNfd190cywgYWxwaGEgPSAwLjIsIGluaXRpYWwgPSAnc2ltcGxlJywgaD01KQ0KZml0X3cyIDwtIHNlcyhzYWxlc193X3RzLCBhbHBoYSA9IDAuNiwgaW5pdGlhbCA9ICdzaW1wbGUnLCBoPTUpDQpmaXRfdzMgPC0gc2VzKHNhbGVzX3dfdHMsIGg9NSkNCg0KcGxvdChzYWxlc193X3RzLCB5bGFiPSdXZWVrbHkgU2FsZXMnLCB4bGFiPSdXZWVrcycpDQpsaW5lcyhmaXR0ZWQoZml0X3cxKSwgY29sPSdibHVlJywgdHlwZT0nbycpDQpsaW5lcyhmaXR0ZWQoZml0X3cyKSwgY29sPSdyZWQnLCB0eXBlPSdvJykNCmxpbmVzKGZpdHRlZChmaXRfdzMpLCBjb2w9J2dyZWVuJywgdHlwZT0nbycpDQpgYGANCg0KYGBge3J9DQpmb3JlY2FzdF93MSA8LSBzZXMoc2FsZXNfd190cywgaD01KQ0Kcm91bmQoYWNjdXJhY3koZm9yZWNhc3RfdzEpLDIpDQoNCnN1bW1hcnkoZm9yZWNhc3RfdzEpDQoNCmF1dG9wbG90KGZvcmVjYXN0X3cxKSArIGF1dG9sYXllcihmaXR0ZWQoZm9yZWNhc3RfdzEpLHNlcmllcz0nRml0dGVkJykgKyB5bGFiKCJXZWVrbHkgU2FsZXMiKSt4bGFiKCJXZWVrcyIpDQpgYGANCg0KYGBge3J9DQojIEV4dHJhY3QgZml0dGVkIHZhbHVlcyBmb3IgZWFjaCBtb2RlbA0KZml0dGVkX3cxIDwtIGZpdHRlZChmaXRfdzEpDQpmaXR0ZWRfdzIgPC0gZml0dGVkKGZpdF93MikNCmZpdHRlZF93MyA8LSBmaXR0ZWQoZml0X3czKQ0KDQojIENhbGN1bGF0ZSBSTVNFIGZvciBlYWNoIG1vZGVsDQpybXNlX3cxIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfd190cywgcHJlZGljdGVkID0gZml0dGVkX3cxKQ0Kcm1zZV93MiA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX3dfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF93MikNCnJtc2VfdzMgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc193X3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfdzMpDQoNCiMgUHJpbnQgUk1TRSB2YWx1ZXMNCmNhdCgiUk1TRSBmb3IgU0VTIE1vZGVsIDEgKGFscGhhID0gMC4yKToiLCBybXNlX3cxLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBTRVMgTW9kZWwgMiAoYWxwaGEgPSAwLjYpOiIsIHJtc2VfdzIsICJcbiIpDQpjYXQoIlJNU0UgZm9yIFNFUyBNb2RlbCAzIChPcHRpbWl6ZWQgYWxwaGEpOiIsIHJtc2VfdzMsICJcbiIpDQoNCmBgYA0KYGBge3J9DQpybXNlX2V4cF9zbV93IDwtIHJtc2VfdzMNCmBgYA0KDQojIyMjIyBEYWlseSBzYWxlcw0KDQpEYWlseSBTYWxlcw0KDQpGb3IgZGFpbHkgZGF0YSwgZXhwb25lbnRpYWwgc21vb3RoaW5nIGNhbiBiZSB1c2VkIHRvIGZvcmVjYXN0IHNob3J0LXRlcm0NCnRyZW5kcyBhbmQgc2Vhc29uYWwgcGF0dGVybnMuIFdoZW4gYXBwbHlpbmcgZXhwb25lbnRpYWwgc21vb3RoaW5nIHRvDQpkYWlseSBkYXRhLCB5b3UgbmVlZCB0byBjb25zaWRlcjoNCg0KLSAgICoqU2Vhc29uYWxpdHkqKjogRGFpbHkgZGF0YSBvZnRlbiBleGhpYml0IHNlYXNvbmFsIHBhdHRlcm5zLCBzdWNoIGFzDQogICAgd2Vla2x5IGN5Y2xlcyAoZS5nLiwgaGlnaGVyIHNhbGVzIG9uIHdlZWtlbmRzKS4NCg0KLSAgICoqSG9saWRheXMgYW5kIHNwZWNpYWwgZXZlbnRzKio6IFRoZXNlIGNhbiBjYXVzZSBpcnJlZ3VsYXIgcGF0dGVybnMNCiAgICBpbiBkYWlseSBkYXRhIHRoYXQgbWF5IG5lZWQgdG8gYmUgYWNjb3VudGVkIGZvci4NCg0KDQpgYGB7cn0NCg0KZml0X2QxIDwtIHNlcyhzYWxlc19kX3RzLCBhbHBoYSA9IDAuMiwgaW5pdGlhbCA9ICdzaW1wbGUnLCBoPTUpDQpmaXRfZDIgPC0gc2VzKHNhbGVzX2RfdHMsIGFscGhhID0gMC42LCBpbml0aWFsID0gJ3NpbXBsZScsIGg9NSkNCmZpdF9kMyA8LSBzZXMoc2FsZXNfZF90cywgaD01KQ0KDQpwbG90KHNhbGVzX2RfdHMsIHlsYWI9J0RhaWx5IFNhbGVzJywgeGxhYj0nRGF5cycpDQpsaW5lcyhmaXR0ZWQoZml0X2QxKSwgY29sPSdibHVlJywgdHlwZT0nbycpDQpsaW5lcyhmaXR0ZWQoZml0X2QyKSwgY29sPSdyZWQnLCB0eXBlPSdvJykNCmxpbmVzKGZpdHRlZChmaXRfZDMpLCBjb2w9J2dyZWVuJywgdHlwZT0nbycpDQpgYGANCg0KYGBge3J9DQpmb3JlY2FzdF9kMSA8LSBzZXMoc2FsZXNfZF90cywgaD01KQ0Kcm91bmQoYWNjdXJhY3koZm9yZWNhc3RfZDEpLDIpDQoNCnN1bW1hcnkoZm9yZWNhc3RfZDEpDQoNCmF1dG9wbG90KGZvcmVjYXN0X2QxKSArIGF1dG9sYXllcihmaXR0ZWQoZm9yZWNhc3RfZDEpLHNlcmllcz0nRml0dGVkJykgKyB5bGFiKCJEYWlseSBTYWxlcyIpK3hsYWIoIkRheXMiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBFeHRyYWN0IGZpdHRlZCB2YWx1ZXMgZm9yIGVhY2ggbW9kZWwNCmZpdHRlZF9kMSA8LSBmaXR0ZWQoZml0X2QxKQ0KZml0dGVkX2QyIDwtIGZpdHRlZChmaXRfZDIpDQpmaXR0ZWRfZDMgPC0gZml0dGVkKGZpdF9kMykNCg0KIyBDYWxjdWxhdGUgUk1TRSBmb3IgZWFjaCBtb2RlbA0Kcm1zZV9kMSA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX2RfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9kMSkNCnJtc2VfZDIgPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19kX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfZDIpDQpybXNlX2QzIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfZF90cywgcHJlZGljdGVkID0gZml0dGVkX2QzKQ0KDQojIFByaW50IFJNU0UgdmFsdWVzDQpjYXQoIlJNU0UgZm9yIFNFUyBNb2RlbCAxIChhbHBoYSA9IDAuMik6Iiwgcm1zZV9kMSwgIlxuIikNCmNhdCgiUk1TRSBmb3IgU0VTIE1vZGVsIDIgKGFscGhhID0gMC42KToiLCBybXNlX2QyLCAiXG4iKQ0KY2F0KCJSTVNFIGZvciBTRVMgTW9kZWwgMyAoT3B0aW1pemVkIGFscGhhKToiLCBybXNlX2QzLCAiXG4iKQ0KDQpgYGANCmBgYHtyfQ0Kcm1zZV9leHBfc21fZCA8LSBybXNlX2QzDQpgYGANCg0KIyMjIEdHTSArIFNBUk1BWA0KDQoNCiMjIyMgTW9udGhseQ0KYGBge3J9DQojIEdHTSBwYXJ0DQojIFN1bW1hcnkgb2YgdGhlIEdHTSBtb2RlbA0Kc3VtbWFyeShnZ20xKSAgIyBBc3N1bWUgZ2dtMV9tIGlzIHRoZSBtb250aGx5IEdHTSBtb2RlbA0KDQojIFByZWRpY3Rpb25zIHVzaW5nIEdHTQ0KcHJlZF9HR01fbSA8LSBwcmVkaWN0KGdnbTEsIG5ld3ggPSBtYXRyaXgoMTpsZW5ndGgoc2FsZXNfbV90cyksIG5jb2wgPSAxKSkNCnByZWRfR0dNX20uaW5zdCA8LSBtYWtlLmluc3RhbnRhbmVvdXMocHJlZF9HR01fbSkNCmBgYA0KYGBge3J9DQojIENvbnZlcnQgcHJlZGljdGlvbnMgdG8gYSB0aW1lIHNlcmllcw0Kc3RhcnRfdGltZV9tIDwtIHN0YXJ0KHNhbGVzX21fdHMpICAjIFN0YXJ0IHRpbWUgZnJvbSBzYWxlc19tX3RzDQpmcmVxdWVuY3lfbSA8LSBmcmVxdWVuY3koc2FsZXNfbV90cykgICMgRnJlcXVlbmN5IGZyb20gc2FsZXNfbV90cw0KDQpwcmVkX0dHTV9tX3ZlYyA8LSB1bmxpc3QocHJlZF9HR01fbS5pbnN0KSAgIyBDb252ZXJ0IHByZWRpY3Rpb25zIHRvIGEgbnVtZXJpYyB2ZWN0b3INCnByZWRfR0dNX21fdHMgPC0gdHMocHJlZF9HR01fbV92ZWMsIHN0YXJ0ID0gc3RhcnRfdGltZV9tLCBmcmVxdWVuY3kgPSBmcmVxdWVuY3lfbSkNCmBgYA0KDQoNCmBgYHtyfQ0KIyBQbG90IGFjdHVhbCB2cyBHR00gcHJlZGljdGlvbnMNCnBsb3Qoc2FsZXNfbV90cywgdHlwZSA9ICJiIiwgeGxhYiA9ICJNb250aCIsIHlsYWIgPSAiTW9udGhseSBTYWxlcyIsIHBjaCA9IDE2LCBsdHkgPSAzLCBjZXggPSAwLjYpDQpsaW5lcyhwcmVkX0dHTV9tX3RzLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCmBgYA0KDQpgYGB7cn0NCiMjIyMgU0FSSU1BWCBSZWZpbmVtZW50LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgR2V0IGZpdHRlZCB2YWx1ZXMgZnJvbSB0aGUgR0dNIG1vZGVsDQpmaXQuc2FsZXNfbSA8LSBmaXR0ZWQoZ2dtMSkNCg0KIyBDaGVjayBsZW5ndGggY29uc2lzdGVuY3kNCmlmIChsZW5ndGgoZml0LnNhbGVzX20pICE9IGxlbmd0aChzYWxlc19tX3RzKSkgew0KICBzdG9wKCJmaXQuc2FsZXNfbSBhbmQgc2FsZXNfbV90cyBsZW5ndGhzIGRvIG5vdCBtYXRjaCIpDQp9DQoNCmBgYA0KDQpgYGB7cn0NCiMgU2NhbGUgR0dNIGZpdHRlZCB2YWx1ZXMgYW5kIHRoZSBjdW11bGF0aXZlIHNhbGVzDQpmaXQuc2FsZXNfbSA8LSBzY2FsZShmaXQuc2FsZXNfbSkNCnNhbGVzX21fdHNfc2NhbGVkIDwtIHNjYWxlKGN1bXN1bShzYWxlc19tX3RzKSkgICMgU2NhbGUgdGhlIGN1bXVsYXRpdmUgc2FsZXMgZm9yIGNvbnZlcmdlbmNlDQpgYGANCg0KDQpgYGB7cn0NCiMgRml0IFNBUklNQVggd2l0aCBHR00gZml0dGVkIHZhbHVlcyBhcyByZWdyZXNzb3JzDQpzYXJpbWFfbSA8LSBBcmltYSgNCiAgc2FsZXNfbV90c19zY2FsZWQsDQogIG9yZGVyID0gYygxLCAwLCAxKSwNCiAgc2Vhc29uYWwgPSBsaXN0KG9yZGVyID0gYygwLCAwLCAxKSwgcGVyaW9kID0gMTIpLCAgIyBNb250aGx5IHNlYXNvbmFsaXR5DQogIHhyZWcgPSBmaXQuc2FsZXNfbQ0KKQ0KDQpzdW1tYXJ5KHNhcmltYV9tKQ0KYGBgDQoNCmBgYHtyfQ0KIyBSZXZlcnNlIHNjYWxpbmcgZm9yIGZpdHRlZCBjdW11bGF0aXZlIHZhbHVlcw0KZml0dGVkX2N1bXVsYXRpdmUgPC0gZml0dGVkKHNhcmltYV9tKQ0KDQpzY2FsaW5nX2NlbnRlciA8LSBhdHRyKHNhbGVzX21fdHNfc2NhbGVkLCAic2NhbGVkOmNlbnRlciIpDQpzY2FsaW5nX3NjYWxlIDwtIGF0dHIoc2FsZXNfbV90c19zY2FsZWQsICJzY2FsZWQ6c2NhbGUiKQ0KDQpmaXR0ZWRfY3VtdWxhdGl2ZV9vcmlnaW5hbCA8LSBmaXR0ZWRfY3VtdWxhdGl2ZSAqIHNjYWxpbmdfc2NhbGUgKyBzY2FsaW5nX2NlbnRlcg0KDQojIENvbnZlcnQgY3VtdWxhdGl2ZSBmaXR0ZWQgdmFsdWVzIHRvIGluc3RhbnRhbmVvdXMgdmFsdWVzDQpmaXR0ZWRfaW5zdGFudGFuZW91cyA8LSBkaWZmKGMoZml0dGVkX2N1bXVsYXRpdmVfb3JpZ2luYWwsIE5BKSkgICMgQWRkIE5BIHRvIGFsaWduIGxlbmd0aHMNCg0KIyBDcmVhdGUgYSB0aW1lIHNlcmllcyBvYmplY3QgZm9yIHRoZSBmaXR0ZWQgaW5zdGFudGFuZW91cyB2YWx1ZXMNCmZpdHRlZF9pbnN0YW50YW5lb3VzX3RzIDwtIHRzKA0KICBmaXR0ZWRfaW5zdGFudGFuZW91cywNCiAgc3RhcnQgPSBzdGFydChzYWxlc19tX3RzKSwNCiAgZnJlcXVlbmN5ID0gZnJlcXVlbmN5KHNhbGVzX21fdHMpDQopDQpgYGANCg0KYGBge3J9DQojIFBsb3QgYWN0dWFsIHZzIGZpdHRlZCBpbnN0YW50YW5lb3VzIHZhbHVlcw0KcGxvdChzYWxlc19tX3RzLCB0eXBlID0gInAiLCBjb2wgPSAiYmx1ZSIsIHBjaCA9IDE2LA0KICAgICBtYWluID0gIk9yaWdpbmFsIHZzIEZpdHRlZCBJbnN0YW50YW5lb3VzIFZhbHVlcyAoTW9udGhseSkiLA0KICAgICB4bGFiID0gIlRpbWUiLCB5bGFiID0gIkluc3RhbnRhbmVvdXMgVmFsdWVzIikNCmxpbmVzKGZpdHRlZF9pbnN0YW50YW5lb3VzX3RzLCBjb2wgPSAicmVkIiwgbHdkID0gMywgbHR5ID0gMSkNCg0KIyBBZGQgbGVnZW5kDQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiT3JpZ2luYWwgc2FsZXMiLCAiRml0dGVkIHNhbGVzIiksDQogICAgICAgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gYyhOQSwgMSksIHBjaCA9IGMoMTYsIE5BKSwgbHdkID0gYyhOQSwgMykpDQpgYGANCg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIFJNU0UgZm9yIGZpdHRlZF9pbnN0YW50YW5lb3VzX3RzIGFnYWluc3Qgc2FsZXNfbV90cw0Kcm1zZV9taXh0dXJlX20gPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBzYWxlc19tX3RzLCBwcmVkaWN0ZWQgPSBmaXR0ZWRfaW5zdGFudGFuZW91c190cykNCg0KIyBQcmludCB0aGUgUk1TRSB2YWx1ZQ0KY2F0KCJSTVNFIGZvciBGaXR0ZWQgSW5zdGFudGFuZW91cyBWYWx1ZXMgKEdHTSArIFNBUklNQVgpOiIsIHJtc2VfbWl4dHVyZV9tLCAiXG4iKQ0KYGBgDQpgYGB7cn0NCnJlc2lkX21peHR1cmVfbSA8LSBzYWxlc19tX3RzIC0gZml0dGVkX2luc3RhbnRhbmVvdXNfdHMNCnRzZGlzcGxheShyZXNpZF9taXh0dXJlX20pDQpgYGANClJlc2lkdWFscyBoYXZlIGF1dG9jb3JyZWxhdGlvbiBhdCBsYWcgMQ0KDQojIyMjIFdlZWtseQ0KDQpgYGB7cn0NCiMjIyMgR0dNLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpzdW1tYXJ5KGdnbTFfdykgIyB0aGlzIG9uZSBpcyBiZXN0IG1vZGVsIGZvdW5kDQoNCg0KcHJlZF9HR01fdzwtIHByZWRpY3QoZ2dtMV93LCBuZXd4PW1hdHJpeCgxOmxlbmd0aChzYWxlc193X3RzKSwgbmNvbD0xKSkNCnByZWRfR0dNX3cuaW5zdDwtIG1ha2UuaW5zdGFudGFuZW91cyhwcmVkX0dHTV93KQ0KIyBzZXQgc2FtZSB0aW1lZnJhbWUgZm9yIEdHTSBwcmVkcw0Kc3RhcnRfdGltZV93IDwtIHN0YXJ0KHNhbGVzX3dfdHMpICAjIEdldCBzdGFydCB0aW1lIGZyb20gc2FsZXNfd190cw0KZnJlcXVlbmN5X3cgPC0gZnJlcXVlbmN5KHNhbGVzX3dfdHMpICAjIEdldCBmcmVxdWVuY3kgZnJvbSBzYWxlc193X3RzDQoNCiMgQ29udmVydCBwcmVkX0dHTSB0byBhIG51bWVyaWMgdmVjdG9yDQpwcmVkX0dHTV93X3ZlYyA8LSB1bmxpc3QocHJlZF9HR01fdy5pbnN0KSAgIyBGbGF0dGVuIHRoZSBsaXN0IHRvIGEgbnVtZXJpYyB2ZWN0b3INCiMgQ3JlYXRlIHRoZSB0aW1lIHNlcmllcyBmb3IgcHJlZF9HR00NCnByZWRfR0dNX3dfdHMgPC0gdHMocHJlZF9HR01fd192ZWMsIHN0YXJ0ID0gc3RhcnRfdGltZV93LCBmcmVxdWVuY3kgPSBmcmVxdWVuY3lfdykNCg0KDQpwbG90KHNhbGVzX3dfdHMsIHR5cGU9ICJiIix4bGFiPSJXZWVrIiwgeWxhYj0iV2Vla2x5IFNhbGVzIiwgIHBjaD0xNiwgbHR5PTMsIGNleD0wLjYpDQpsaW5lcyhwcmVkX0dHTV93X3RzLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCg0KDQpgYGANCg0KYGBge3J9DQojIFNBUk1BWCByZWZpbmVtZW50DQpmaXQuc2FsZXNfdyA8LSBmaXR0ZWQoZ2dtMV93KSAgIyBQcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIEdHTSBtb2RlbA0KDQppZiAobGVuZ3RoKGZpdC5zYWxlc193KSAhPSBsZW5ndGgoc2FsZXNfd190cykpIHsNCiAgc3RvcCgiZml0LnNhbGVzX3cgYW5kIHNhbGVzX3dfdHMgbGVuZ3RocyBkbyBub3QgbWF0Y2giKQ0KfQ0KDQpgYGANCg0KYGBge3J9DQpmaXQuc2FsZXNfdyA8LSBzY2FsZShmaXQuc2FsZXNfdykgIyBzY2FsZSByZWdyZXNvciB0byBtYWtlIGNvbnZlcmdlbmNlDQoNCnNhbGVzX3dfdHNfc2NhbGVkIDwtIHNjYWxlKGN1bXN1bShzYWxlc193X3RzKSkgICMgU2NhbGUgdGhlIHRpbWUgc2VyaWVzIGJlY2F1c2UgaWYgbm90IHdpbGwgbm90IHJlYWNoIGNvbnZlcmdlbmNlDQoNCnNhcmltYV93IDwtIEFyaW1hKA0KICBzYWxlc193X3RzX3NjYWxlZCwgDQogIG9yZGVyID0gYygxLCAwLCAxKSwgDQogIHNlYXNvbmFsID0gbGlzdChvcmRlciA9IGMoMCwgMCwgMSksIHBlcmlvZCA9IDUyKSwgDQogIHhyZWcgPSBmaXQuc2FsZXNfdyAjIHRoaXMgaXMgdGhlIEdHTSBmaXR0ZWQgdmFsdWVzDQopDQoNCnN1bW1hcnkoc2FyaW1hX3cpDQoNCmBgYA0KYGBge3J9DQojIGdldCBmaXR0ZWQgdmFsdWVzDQojIEV4dHJhY3QgdGhlIGZpdHRlZCBjdW11bGF0aXZlIHZhbHVlcyBmcm9tIHRoZSBTQVJJTUEgbW9kZWwNCmZpdHRlZF9jdW11bGF0aXZlIDwtIGZpdHRlZChzYXJpbWFfdykNCg0KIyBSZXZlcnNlIHNjYWxpbmcgdHJhbnNmb3JtYXRpb24gdG8gZ2V0IGZpdHRlZCBjdW11bGF0aXZlIHZhbHVlcyBpbiB0aGUgb3JpZ2luYWwgc2NhbGUNCnNjYWxpbmdfY2VudGVyIDwtIGF0dHIoc2FsZXNfd190c19zY2FsZWQsICJzY2FsZWQ6Y2VudGVyIikNCnNjYWxpbmdfc2NhbGUgPC0gYXR0cihzYWxlc193X3RzX3NjYWxlZCwgInNjYWxlZDpzY2FsZSIpDQoNCmZpdHRlZF9jdW11bGF0aXZlX29yaWdpbmFsIDwtIGZpdHRlZF9jdW11bGF0aXZlICogc2NhbGluZ19zY2FsZSArIHNjYWxpbmdfY2VudGVyDQoNCiMgQ29udmVydCBjdW11bGF0aXZlIGZpdHRlZCB2YWx1ZXMgdG8gaW5zdGFudGFuZW91cyB2YWx1ZXMNCmZpdHRlZF9pbnN0YW50YW5lb3VzIDwtIGRpZmYoYyhmaXR0ZWRfY3VtdWxhdGl2ZV9vcmlnaW5hbCwgTkEpKSAgIyBBZGQgTkEgdG8gYWxpZ24gbGVuZ3Rocw0KDQojIENyZWF0ZSBhIHRpbWUgc2VyaWVzIG9iamVjdCBmb3IgdGhlIGZpdHRlZCBpbnN0YW50YW5lb3VzIHZhbHVlcw0KZml0dGVkX2luc3RhbnRhbmVvdXNfdHMgPC0gdHMoDQogIGZpdHRlZF9pbnN0YW50YW5lb3VzLCANCiAgc3RhcnQgPSBzdGFydChzYWxlc193X3RzKSwgDQogIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeShzYWxlc193X3RzKQ0KKQ0KDQpgYGANCg0KYGBge3J9DQojIFBsb3Qgb3JpZ2luYWwgaW5zdGFudGFuZW91cyB2YWx1ZXMgdnMgZml0dGVkIGluc3RhbnRhbmVvdXMgdmFsdWVzDQpwbG90KHNhbGVzX3dfdHMsIHR5cGUgPSAicCIsIGNvbCA9ICJibHVlIiwgcGNoID0gMTYsDQogICAgIG1haW4gPSAiT3JpZ2luYWwgdnMgRml0dGVkIEluc3RhbnRhbmVvdXMgVmFsdWVzIiwNCiAgICAgeGxhYiA9ICJUaW1lIiwgeWxhYiA9ICJJbnN0YW50YW5lb3VzIFZhbHVlcyIpDQoNCiMgQWRkIHRoZSBmaXR0ZWQgaW5zdGFudGFuZW91cyB2YWx1ZXMgYXMgYSBsaW5lDQpsaW5lcyhmaXR0ZWRfaW5zdGFudGFuZW91c190cywgY29sID0gInJlZCIsIGx3ZCA9IDMsIGx0eSA9IDEpDQoNCiMgQWRkIGxlZ2VuZA0KbGVnZW5kKCJib3R0b21yaWdodCIsIGxlZ2VuZCA9IGMoIk9yaWdpbmFsIEluc3RhbnRhbmVvdXMiLCAiRml0dGVkIEluc3RhbnRhbmVvdXMiKSwNCiAgICAgICBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSBjKE5BLCAxKSwgcGNoID0gYygxNiwgTkEpLCBsd2QgPSBjKE5BLCAzKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBSZXNpZHVhbHMNCiMgU3RlcCAxOiBFeHRyYWN0IHJlc2lkdWFscyBmcm9tIHRoZSBTQVJJTUEgbW9kZWwNCnJlc2lkX3cgPC0gcmVzaWR1YWxzKHNhcmltYV93KQ0KDQojIFN0ZXAgMjogVmlzdWFsaXplIHJlc2lkdWFscw0KIyBUaW1lIHNlcmllcyBwbG90IG9mIHJlc2lkdWFscw0KdHNkaXNwbGF5KHJlc2lkX3csIG1haW4gPSAiUmVzaWR1YWwgRGlhZ25vc3RpY3MgZm9yIFNBUklNQSBNb2RlbCIpDQoNCiMgU3RlcCAzOiBUZXN0IHJlc2lkdWFscyBmb3Igc3RhdGlvbmFyaXR5DQphZGZfdGVzdCA8LSBhZGYudGVzdChyZXNpZF93KQ0KY2F0KCJBREYgVGVzdCBwLXZhbHVlOiIsIGFkZl90ZXN0JHAudmFsdWUsICJcbiIpDQoNCmlmIChhZGZfdGVzdCRwLnZhbHVlIDwgMC4wNSkgew0KICBjYXQoIlRoZSByZXNpZHVhbHMgYXJlIHN0YXRpb25hcnkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJUaGUgcmVzaWR1YWxzIGFyZSBub3Qgc3RhdGlvbmFyeS5cbiIpDQp9DQoNCiMgU3RlcCA0OiBUZXN0IHJlc2lkdWFscyBmb3Igd2hpdGUgbm9pc2UgKG5vIGF1dG9jb3JyZWxhdGlvbikNCg0KbGp1bmdfYm94X3Rlc3QgPC0gQm94LnRlc3QocmVzaWRfdywgbGFnID0gMjAsIHR5cGUgPSAiTGp1bmctQm94IikNCmNhdCgiTGp1bmctQm94IFRlc3QgcC12YWx1ZToiLCBsanVuZ19ib3hfdGVzdCRwLnZhbHVlLCAiXG4iKQ0KDQppZiAobGp1bmdfYm94X3Rlc3QkcC52YWx1ZSA+IDAuMDUpIHsNCiAgY2F0KCJUaGUgcmVzaWR1YWxzIHJlc2VtYmxlIHdoaXRlIG5vaXNlICh1bmNvcnJlbGF0ZWQpLlxuIikNCn0gZWxzZSB7DQogIGNhdCgiVGhlIHJlc2lkdWFscyBzaG93IHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbi5cbiIpDQp9DQoNCmBgYA0KDQpTdGF0aW9uYXJ5IHJlc2lkdWFscyBidXQgd2l0aCBzaWduaWZpY2FudCBjb3JyZWxhdGlvbg0KDQpgYGB7cn0NCiMjIyMgUk1TRSBmb3IgU0FSSU1BWCBQcmVkaWN0aW9ucyAjIyMjDQpybXNlX21peHR1cmVfdyA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IHNhbGVzX3dfdHMsIHByZWRpY3RlZCA9IGZpdHRlZF9pbnN0YW50YW5lb3VzX3RzKQ0KDQojIFByaW50IFJNU0UgZm9yIFNBUklNQVgNCmNhdCgiUk1TRSBmb3IgU0FSSU1BWCBQcmVkaWN0aW9uczoiLCBybXNlX21peHR1cmVfdywgIlxuIikNCmBgYA0KIyMjIyBEYWlseQ0KDQpgYGB7cn0NCiMgU2NhbGluZyB0aGUgc2FsZXMgZGF0YQ0Kc2FsZXNfbWluIDwtIG1pbihzYWxlc19kX3RzKQ0Kc2FsZXNfbWF4IDwtIG1heChzYWxlc19kX3RzKQ0Kc2FsZXNfc2NhbGVkIDwtIChzYWxlc19kX3RzIC0gc2FsZXNfbWluKSAvIChzYWxlc19tYXggLSBzYWxlc19taW4pDQoNCiMgVmlldyBzY2FsZWQgZGF0YQ0Kc3VtbWFyeShzYWxlc19zY2FsZWQpDQpwbG90KHNhbGVzX3NjYWxlZCwgdHlwZSA9ICJsIiwgbWFpbiA9ICJTY2FsZWQgRGFpbHkgU2FsZXMiLCB4bGFiID0gIkRheSIsIHlsYWIgPSAiU2NhbGVkIFNhbGVzIikNCg0KIyMjIyBHR00tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEZpdCBHR00gbW9kZWwgdXNpbmcgc2NhbGVkIGRhdGENCmdnbTFfZCA8LSBHR00oc2FsZXNfc2NhbGVkLCBtdCA9ICdiYXNlJywgZGlzcGxheSA9IFQpDQpzdW1tYXJ5KGdnbTFfZCkNCg0KIyBQcmVkaWN0aW9ucyB1c2luZyBHR00NCnByZWRfR0dNX2QgPC0gcHJlZGljdChnZ20xX2QsIG5ld3ggPSBtYXRyaXgoMTpsZW5ndGgoc2FsZXNfc2NhbGVkKSwgbmNvbCA9IDEpKQ0KcHJlZF9HR01fZC5pbnN0IDwtIG1ha2UuaW5zdGFudGFuZW91cyhwcmVkX0dHTV9kKQ0KDQojIENvbnZlcnQgcHJlZGljdGlvbnMgdG8gYSB0aW1lIHNlcmllcw0Kc3RhcnRfdGltZV9kIDwtIHN0YXJ0KHNhbGVzX3NjYWxlZCkgICMgU3RhcnQgdGltZSBmcm9tIHNjYWxlZCBzYWxlcw0KZnJlcXVlbmN5X2QgPC0gZnJlcXVlbmN5KHNhbGVzX3NjYWxlZCkgICMgRnJlcXVlbmN5IGZyb20gc2NhbGVkIHNhbGVzDQoNCnByZWRfR0dNX2RfdmVjIDwtIHVubGlzdChwcmVkX0dHTV9kLmluc3QpICAjIENvbnZlcnQgcHJlZGljdGlvbnMgdG8gYSBudW1lcmljIHZlY3Rvcg0KcHJlZF9HR01fZF90cyA8LSB0cyhwcmVkX0dHTV9kX3ZlYywgc3RhcnQgPSBzdGFydF90aW1lX2QsIGZyZXF1ZW5jeSA9IGZyZXF1ZW5jeV9kKQ0KDQojIFBsb3Qgc2NhbGVkIEdHTSBwcmVkaWN0aW9ucw0KcGxvdChzYWxlc19zY2FsZWQsIHR5cGUgPSAiYiIsIHhsYWIgPSAiRGF5IiwgeWxhYiA9ICJTY2FsZWQgRGFpbHkgU2FsZXMiLCBwY2ggPSAxNiwgbHR5ID0gMywgY2V4ID0gMC42KQ0KbGluZXMocHJlZF9HR01fZF90cywgY29sID0gInJlZCIsIGx0eSA9IDIpDQoNCiMjIyMgU0FSSU1BWCBSZWZpbmVtZW50LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgVXNlIGluc3RhbnRhbmVvdXMgZml0dGVkIHZhbHVlcyBmcm9tIHRoZSBHR00gbW9kZWwNCmZpdC5zYWxlc19kX2luc3RhbnRhbmVvdXMgPC0gcHJlZF9HR01fZC5pbnN0DQoNCiMgRW5zdXJlIGxlbmd0aHMgbWF0Y2gNCmlmIChsZW5ndGgoZml0LnNhbGVzX2RfaW5zdGFudGFuZW91cykgIT0gbGVuZ3RoKHNhbGVzX3NjYWxlZCkpIHsNCiAgc3RvcCgiSW5zdGFudGFuZW91cyBmaXR0ZWQgdmFsdWVzIGFuZCBzY2FsZWQgc2FsZXMgZGF0YSBsZW5ndGhzIGRvIG5vdCBtYXRjaCEiKQ0KfQ0KDQojIEZpdCBTQVJJTUFYIHdpdGggaW5zdGFudGFuZW91cyBHR00gZml0dGVkIHZhbHVlcyBhcyByZWdyZXNzb3JzDQpzYXJpbWFfZCA8LSBhdXRvLmFyaW1hKA0KICBzYWxlc19zY2FsZWQsDQogIHNlYXNvbmFsID0gVFJVRSwgICAgICAgICAgICAgICAgICMgRW5hYmxlIHNlYXNvbmFsIGNvbXBvbmVudHMNCiAgeHJlZyA9IGZpdC5zYWxlc19kX2luc3RhbnRhbmVvdXMsICMgVXNlIGluc3RhbnRhbmVvdXMgR0dNIHZhbHVlcyBhcyByZWdyZXNzb3JzDQogIHN0ZXB3aXNlID0gVFJVRSwgICAgICAgICAgICAgICAgICMgRW5hYmxlIHN0ZXB3aXNlIHNlbGVjdGlvbiAoZmFzdGVyKQ0KICBhcHByb3hpbWF0aW9uID0gRkFMU0UgICAgICAgICAgICAjIFVzZSBleGFjdCBtYXhpbXVtIGxpa2VsaWhvb2QNCikNCg0Kc3VtbWFyeShzYXJpbWFfZCkNCg0KIyBFeHRyYWN0IGZpdHRlZCBzY2FsZWQgdmFsdWVzIGZyb20gdGhlIFNBUklNQVggbW9kZWwNCmZpdHRlZF9zY2FsZWQgPC0gZml0dGVkKHNhcmltYV9kKQ0KDQojIFJldmVyc2Ugc2NhbGluZyBmb3IgZmluYWwgZml0dGVkIGluc3RhbnRhbmVvdXMgdmFsdWVzDQpmaXR0ZWRfaW5zdGFudGFuZW91c190cyA8LSBmaXR0ZWRfc2NhbGVkICogKHNhbGVzX21heCAtIHNhbGVzX21pbikgKyBzYWxlc19taW4NCg0KIyBSZXZlcnNlIHNjYWxpbmcgZm9yIEdHTSBwcmVkaWN0aW9ucw0KcHJlZF9HR01fZF9vcmlnaW5hbCA8LSBwcmVkX0dHTV9kX3RzICogKHNhbGVzX21heCAtIHNhbGVzX21pbikgKyBzYWxlc19taW4NCg0KIyBQbG90IGFjdHVhbCB2cyBmaXR0ZWQgaW5zdGFudGFuZW91cyB2YWx1ZXMNCnBsb3Qoc2FsZXNfZF90cywgdHlwZSA9ICJwIiwgY29sID0gImJsdWUiLCBwY2ggPSAxNiwNCiAgICAgbWFpbiA9ICJPcmlnaW5hbCB2cyBGaXR0ZWQgSW5zdGFudGFuZW91cyBWYWx1ZXMgKERhaWx5KSIsDQogICAgIHhsYWIgPSAiVGltZSIsIHlsYWIgPSAiSW5zdGFudGFuZW91cyBWYWx1ZXMiKQ0KbGluZXMoZml0dGVkX2luc3RhbnRhbmVvdXNfdHMsIGNvbCA9ICJyZWQiLCBsd2QgPSAzLCBsdHkgPSAxKQ0KDQojIEFkZCBsZWdlbmQNCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJPcmlnaW5hbCBJbnN0YW50YW5lb3VzIiwgIkZpdHRlZCBJbnN0YW50YW5lb3VzIiksDQogICAgICAgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gYyhOQSwgMSksIHBjaCA9IGMoMTYsIE5BKSwgbHdkID0gYyhOQSwgMykpDQoNCmBgYA0KDQpgYGB7cn0NCiMjIyMgUmVzaWR1YWxzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgRXh0cmFjdCByZXNpZHVhbHMgZnJvbSB0aGUgU0FSSU1BIG1vZGVsDQpyZXNpZF9kIDwtIHJlc2lkdWFscyhzYXJpbWFfZCkNCg0KIyBWaXN1YWxpemUgcmVzaWR1YWxzDQp0c2Rpc3BsYXkocmVzaWRfZCwgbWFpbiA9ICJSZXNpZHVhbCBEaWFnbm9zdGljcyBmb3IgU0FSSU1BIE1vZGVsIikNCg0KIyBUZXN0IHJlc2lkdWFscyBmb3Igc3RhdGlvbmFyaXR5DQphZGZfdGVzdCA8LSBhZGYudGVzdChyZXNpZF9kKQ0KY2F0KCJBREYgVGVzdCBwLXZhbHVlOiIsIGFkZl90ZXN0JHAudmFsdWUsICJcbiIpDQoNCmlmIChhZGZfdGVzdCRwLnZhbHVlIDwgMC4wNSkgew0KICBjYXQoIlRoZSByZXNpZHVhbHMgYXJlIHN0YXRpb25hcnkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJUaGUgcmVzaWR1YWxzIGFyZSBub3Qgc3RhdGlvbmFyeS5cbiIpDQp9DQoNCiMgVGVzdCByZXNpZHVhbHMgZm9yIHdoaXRlIG5vaXNlIChubyBhdXRvY29ycmVsYXRpb24pDQpsanVuZ19ib3hfdGVzdCA8LSBCb3gudGVzdChyZXNpZF9kLCBsYWcgPSAyMCwgdHlwZSA9ICJManVuZy1Cb3giKQ0KY2F0KCJManVuZy1Cb3ggVGVzdCBwLXZhbHVlOiIsIGxqdW5nX2JveF90ZXN0JHAudmFsdWUsICJcbiIpDQoNCmlmIChsanVuZ19ib3hfdGVzdCRwLnZhbHVlID4gMC4wNSkgew0KICBjYXQoIlRoZSByZXNpZHVhbHMgcmVzZW1ibGUgd2hpdGUgbm9pc2UgKHVuY29ycmVsYXRlZCkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJUaGUgcmVzaWR1YWxzIHNob3cgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uLlxuIikNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KIyMjIyBSTVNFIGZvciBTQVJJTUFYIFByZWRpY3Rpb25zICMjIyMNCnJtc2VfbWl4dHVyZV9kIDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gc2FsZXNfZF90cywgcHJlZGljdGVkID0gZml0dGVkX2luc3RhbnRhbmVvdXNfdHMpDQoNCiMgUHJpbnQgUk1TRSBmb3IgU0FSSU1BWA0KY2F0KCJSTVNFIGZvciBTQVJJTUFYIFByZWRpY3Rpb25zOiIsIHJtc2VfbWl4dHVyZV9kLCAiXG4iKQ0KYGBgDQoNCg0KIyMjIFByb3BoZXQNCg0KVGhpcyBtb2RlbCB3YXMgaW50cm9kdWNlZCBieSBGYWNlYm9vayAoW1MuIEouIFRheWxvciAmIExldGhhbSwNCjIwMThdKGh0dHBzOi8vb3RleHRzLmNvbS9mcHAzL3Byb3BoZXQuaHRtbCNyZWYtcHJvcGhldCkpLCBvcmlnaW5hbGx5IGZvcg0KZm9yZWNhc3RpbmcgZGFpbHkgZGF0YSB3aXRoIHdlZWtseSBhbmQgeWVhcmx5IHNlYXNvbmFsaXR5LCBwbHVzIGhvbGlkYXkNCmVmZmVjdHMuIEl0IHdhcyBsYXRlciBleHRlbmRlZCB0byBjb3ZlciBtb3JlIHR5cGVzIG9mIHNlYXNvbmFsIGRhdGEuIEl0DQp3b3JrcyBiZXN0IHdpdGggdGltZSBzZXJpZXMgdGhhdCBoYXZlIHN0cm9uZyBzZWFzb25hbGl0eSBhbmQgc2V2ZXJhbA0Kc2Vhc29ucyBvZiBoaXN0b3JpY2FsIGRhdGEuDQoNClByb3BoZXQgY2FuIGJlIGNvbnNpZGVyZWQgYSBub25saW5lYXIgcmVncmVzc2lvbiBtb2RlbCAoQ2hhcHRlcg0KWzddKGh0dHBzOi8vb3RleHRzLmNvbS9mcHAzL3JlZ3Jlc3Npb24uaHRtbCNyZWdyZXNzaW9uKSksIG9mIHRoZSBmb3JtDQp5dD1nKHQpK3ModCkraCh0KSvOtXQsIHdoZXJlIGcodCkgZGVzY3JpYmVzIGEgcGllY2V3aXNlLWxpbmVhciB0cmVuZCAob3INCiJncm93dGggdGVybSIpLCBzKHQpIGRlc2NyaWJlcyB0aGUgdmFyaW91cyBzZWFzb25hbCBwYXR0ZXJucywgaCh0KQ0KY2FwdHVyZXMgdGhlIGhvbGlkYXkgZWZmZWN0cywgYW5kIM61dCBpcyBhIHdoaXRlIG5vaXNlIGVycm9yIHRlcm0uDQoNCi0gICBUaGUga25vdHMgKG9yIGNoYW5nZXBvaW50cykgZm9yIHRoZSBwaWVjZXdpc2UtbGluZWFyIHRyZW5kIGFyZQ0KICAgIGF1dG9tYXRpY2FsbHkgc2VsZWN0ZWQgaWYgbm90IGV4cGxpY2l0bHkgc3BlY2lmaWVkLiBPcHRpb25hbGx5LCBhDQogICAgbG9naXN0aWMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gc2V0IGFuIHVwcGVyIGJvdW5kIG9uIHRoZSB0cmVuZC4NCg0KLSAgIFRoZSBzZWFzb25hbCBjb21wb25lbnQgY29uc2lzdHMgb2YgRm91cmllciB0ZXJtcyBvZiB0aGUgcmVsZXZhbnQNCiAgICBwZXJpb2RzLiBCeSBkZWZhdWx0LCBvcmRlciAxMCBpcyB1c2VkIGZvciBhbm51YWwgc2Vhc29uYWxpdHkgYW5kDQogICAgb3JkZXIgMyBpcyB1c2VkIGZvciB3ZWVrbHkgc2Vhc29uYWxpdHkuDQoNCi0gICBIb2xpZGF5IGVmZmVjdHMgYXJlIGFkZGVkIGFzIHNpbXBsZSBkdW1teSB2YXJpYWJsZXMuDQoNCi0gICBUaGUgbW9kZWwgaXMgZXN0aW1hdGVkIHVzaW5nIGEgQmF5ZXNpYW4gYXBwcm9hY2ggdG8gYWxsb3cgZm9yDQogICAgYXV0b21hdGljIHNlbGVjdGlvbiBvZiB0aGUgY2hhbmdlcG9pbnRzIGFuZCBvdGhlciBtb2RlbA0KICAgIGNoYXJhY3RlcmlzdGljcy4NCg0KYGBge3J9DQpsaWJyYXJ5KHByb3BoZXQpDQpgYGANCg0KVGhlIGlucHV0IHRvIFByb3BoZXQgaXMgW2Fsd2F5c117LnVuZGVybGluZX0gYSBkYXRhZnJhbWUgd2l0aCB0d28NCmNvbHVtbnM6IGRzIGFuZCB5IC4gKipUaGUgZHMgKGRhdGVzdGFtcCkgY29sdW1uIHNob3VsZCBiZSBvZiBhIGZvcm1hdCwNCmlkZWFsbHkgWVlZWS1NTS1ERCBmb3IgYSBkYXRlIG9yIFlZWVktTU0tREQgSEg6TU06U1MgZm9yIGEgdGltZXN0YW1wKiouDQpUaGUgeSBjb2x1bW4gW211c3Rdey51bmRlcmxpbmV9IGJlIG51bWVyaWMsIGFuZCByZXByZXNlbnRzIHRoZQ0KbWVhc3VyZW1lbnQgd2Ugd2lzaCB0byBmb3JlY2FzdC4NCg0KIyMjIyBNb250aGx5IHNhbGVzDQoNCmBgYHtyfQ0KIyBzYWxlcyBtb250bHkNCmdncGxvdChkZl9tZXJnZWRfbSwgYWVzKHg9bW9udGgsIHk9c2FsZXNfbSkpICsNCiAgZ2VvbV9saW5lKCkgKyBnZ3RpdGxlKCJNb250aGx5IFNhbGVzIG9mIFJlc3RhdXJhbnQiKQ0KDQpoZWFkKGRmX21lcmdlZF9tKQ0KYGBgDQoNCmBgYHtyfQ0KI1Byb3BoZXQgbW9kZWwNCiMgbW9kZWwgd2l0aCBubyBzZWFzb25hbGl0eQ0KZGZfcHJvcGhldF9tIDwtIGRmX21lcmdlZF9tWzE6Ml0NCmhlYWQoZGZfcHJvcGhldF9tKQ0KY29sbmFtZXMoZGZfcHJvcGhldF9tKSA9IGMoImRzIiwgInkiKQ0KZGZfcHJvcGhldF9tJHkgPC0gZXhwKGRmX3Byb3BoZXRfbSR5KQ0KcHJvcGhldF9zYWxlc19tIDwtIHByb3BoZXQoZGZfcHJvcGhldF9tKQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChkZl9wcm9waGV0X20pDQpgYGANCg0KYGBge3J9DQojIFN0ZXAgMjogQ3JlYXRlIGEgZnV0dXJlIGRhdGFmcmFtZSBmb3IgdGhlIG5leHQgMTQgbW9udGhzDQpmdXR1cmVfc2FsZXNfbSA8LSBtYWtlX2Z1dHVyZV9kYXRhZnJhbWUoDQogIHByb3BoZXRfc2FsZXNfbSwNCiAgcGVyaW9kcyA9IDE0LCAgICAgICAgICAgIyBGb3JlY2FzdCBmb3IgMTQgbW9udGhzDQogIGZyZXEgPSAnbW9udGgnLCAgICAgICAgICMgTW9udGhseSBmcmVxdWVuY3kNCiAgaW5jbHVkZV9oaXN0b3J5ID0gVFJVRSAgIyBJbmNsdWRlIGhpc3RvcmljYWwgZGF0YSBpbiB0aGUgZnV0dXJlIGRhdGFmcmFtZQ0KKQ0KdGFpbChmdXR1cmVfc2FsZXNfbSkNCmBgYA0KDQpgYGB7cn0NCmZvcmVjYXN0X3NhbGVzX20gPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX20sIGZ1dHVyZV9zYWxlc19tKQ0KdGFpbChmb3JlY2FzdF9zYWxlc19tW2MoJ2RzJywgJ3loYXQnLCAneWhhdF9sb3dlcicsICd5aGF0X3VwcGVyJyldKQ0KDQpwbG90KHByb3BoZXRfc2FsZXNfbSwgZm9yZWNhc3Rfc2FsZXNfbSkNCmBgYA0KDQpgYGB7cn0NCnByb3BoZXRfcGxvdF9jb21wb25lbnRzKHByb3BoZXRfc2FsZXNfbSwgZm9yZWNhc3Rfc2FsZXNfbSkNCmBgYA0KDQpgYGB7cn0NCmR5cGxvdC5wcm9waGV0KHByb3BoZXRfc2FsZXNfbSwgZm9yZWNhc3Rfc2FsZXNfbSkNCmBgYA0KDQpgYGB7cn0NCiNVc2UgdGhlIG9yaWdpbmFsIGRhdGFmcmFtZSB0byBnZXQgdGhlIGZpdHRlZCB2YWx1ZXMNCmZpdHRlZF92YWx1ZXMgPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX20sIGRmX3Byb3BoZXRfbSkNCg0KIyBFeHRyYWN0IHRoZSBmaXR0ZWQgdmFsdWVzIChjb2x1bW4gJ3loYXQnIGNvbnRhaW5zIHRoZSBmaXR0ZWQgdmFsdWVzKQ0KZml0dGVkX3kgPC0gZml0dGVkX3ZhbHVlcyR5aGF0DQoNCiMgQ2FsY3VsYXRlIFJNU0UNCg0KYWN0dWFsX3kgPC0gZGZfcHJvcGhldF9tJHkgICMgQWN0dWFsIHNhbGVzIHZhbHVlcw0Kcm1zZV9wcm9waGV0X20gPC0gY2FsY3VsYXRlX3Jtc2Uob2JzZXJ2ZWQgPSBhY3R1YWxfeSwgcHJlZGljdGVkID0gZml0dGVkX3kpDQoNCiMgUHJpbnQgUk1TRQ0KY2F0KCJSTVNFIGZvciBQcm9waGV0IEZpdHRlZCBWYWx1ZXM6Iiwgcm1zZV9wcm9waGV0X20sICJcbiIpDQpgYGANClJlc2lkdWFscyBmb3IgcHJvcGhldA0KYGBge3J9DQojIENhbGN1bGF0ZSBSZXNpZHVhbHMNCnJlc2lkdWFsc19wcm9waGV0IDwtIGFjdHVhbF95IC0gZml0dGVkX3kgICMgUmVzaWR1YWxzID0gQWN0dWFsIC0gRml0dGVkDQoNCiMgIFZpc3VhbGl6ZSBSZXNpZHVhbHMgdXNpbmcgdHNkaXNwbGF5DQoNCnRzZGlzcGxheShyZXNpZHVhbHNfcHJvcGhldCwgbWFpbiA9ICJSZXNpZHVhbCBEaWFnbm9zdGljcyBmb3IgUHJvcGhldCBNb2RlbCIpDQoNCiMgIFBlcmZvcm0gQURGIFRlc3QgZm9yIFN0YXRpb25hcml0eQ0KDQphZGZfdGVzdCA8LSBhZGYudGVzdChyZXNpZHVhbHNfcHJvcGhldCkNCmNhdCgiQURGIFRlc3QgcC12YWx1ZToiLCBhZGZfdGVzdCRwLnZhbHVlLCAiXG4iKQ0KDQppZiAoYWRmX3Rlc3QkcC52YWx1ZSA8IDAuMDUpIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIHN0YXRpb25hcnkgKHJlamVjdCBIMCkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIG5vdCBzdGF0aW9uYXJ5IChmYWlsIHRvIHJlamVjdCBIMCkuXG4iKQ0KfQ0KDQojICBQZXJmb3JtIFNlcmlhbCBDb3JyZWxhdGlvbiBUZXN0DQpsanVuZ19ib3hfdGVzdCA8LSBCb3gudGVzdChyZXNpZHVhbHNfcHJvcGhldCwgbGFnID0gMTAsIHR5cGUgPSAiTGp1bmctQm94IikNCmNhdCgiTGp1bmctQm94IFRlc3QgcC12YWx1ZToiLCBsanVuZ19ib3hfdGVzdCRwLnZhbHVlLCAiXG4iKQ0KDQppZiAobGp1bmdfYm94X3Rlc3QkcC52YWx1ZSA+IDAuMDUpIHsNCiAgY2F0KCJSZXNpZHVhbHMgcmVzZW1ibGUgd2hpdGUgbm9pc2UgKG5vIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbikuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJSZXNpZHVhbHMgc2hvdyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24uXG4iKQ0KfQ0KDQpgYGANCg0KDQojIyMjIFdlZWtseSBzYWxlcw0KDQpgYGB7cn0NCmdncGxvdChkZl9tZXJnZWRfdywgYWVzKHg9d2VlaywgeT1zYWxlc193KSkgKw0KICBnZW9tX2xpbmUoKSArIGdndGl0bGUoIldlZWtseSBTYWxlcyBvZiBSZXN0YXVyYW50IikNCmBgYA0KDQpgYGB7cn0NCmhlYWQoZGZfbWVyZ2VkX3cpDQpgYGANCg0KYGBge3J9DQojUHJvcGhldCBtb2RlbA0KIyBtb2RlbCB3aXRoIG5vIHNlYXNvbmFsaXR5DQpkZl9wcm9waGV0X3cgPC0gZGZfbWVyZ2VkX3dbMToyXQ0KY29sbmFtZXMoZGZfcHJvcGhldF93KSA9IGMoImRzIiwgInkiKQ0KZGZfcHJvcGhldF93JHkgPC0gZXhwKGRmX3Byb3BoZXRfdyR5KQ0KZGZfcHJvcGhldF93DQoNCg0KcHJvcGhldF9zYWxlc193IDwtIHByb3BoZXQoZGZfcHJvcGhldF93KQ0KYGBgDQoNClByZWRpY3Rpb25zIGFyZSBtYWRlIG9uIGEgZGF0YWZyYW1lIHdpdGggYSBjb2x1bW4gYGRzYCBjb250YWluaW5nIHRoZQ0KZGF0ZXMgZm9yIHdoaWNoIHByZWRpY3Rpb25zIGFyZSB0byBiZSBtYWRlLiBUaGUgYG1ha2VfZnV0dXJlX2RhdGFmcmFtZWANCmZ1bmN0aW9uIHRha2VzIHRoZSBtb2RlbCBvYmplY3QgYW5kIGEgbnVtYmVyIG9mIHBlcmlvZHMgdG8gZm9yZWNhc3QgYW5kDQpwcm9kdWNlcyBhIHN1aXRhYmxlIGRhdGFmcmFtZS4gQnkgZGVmYXVsdCBpdCB3aWxsIGFsc28gaW5jbHVkZSB0aGUNCmhpc3RvcmljYWwgZGF0ZXMgc28gd2UgY2FuIGV2YWx1YXRlIGluLXNhbXBsZSBmaXQuDQoNCmBgYHtyfQ0KZnV0dXJlX3NhbGVzX3cgPC0gbWFrZV9mdXR1cmVfZGF0YWZyYW1lKHByb3BoZXRfc2FsZXNfdywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kcyA9IDUyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZXEgPSAnd2VlaycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZV9oaXN0b3J5ID0gVCkNCnRhaWwoZnV0dXJlX3NhbGVzX3cpDQpgYGANCg0KQXMgd2l0aCBtb3N0IG1vZGVsaW5nIHByb2NlZHVyZXMgaW4gUiwgd2UgdXNlIHRoZSBnZW5lcmljIGBwcmVkaWN0YA0KZnVuY3Rpb24gdG8gZ2V0IG91ciBmb3JlY2FzdC4gVGhlIGBmb3JlY2FzdGAgb2JqZWN0IGlzIGEgZGF0YWZyYW1lIHdpdGgNCmEgY29sdW1uIGB5aGF0YCBjb250YWluaW5nIHRoZSBmb3JlY2FzdC4gSXQgaGFzIGFkZGl0aW9uYWwgY29sdW1ucyBmb3INCnVuY2VydGFpbnR5IGludGVydmFscyBhbmQgc2Vhc29uYWwgY29tcG9uZW50cy4NCg0KYGBge3J9DQojIFINCmZvcmVjYXN0X3NhbGVzX3cgPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX3csIGZ1dHVyZV9zYWxlc193KQ0KdGFpbChmb3JlY2FzdF9zYWxlc193W2MoJ2RzJywgJ3loYXQnLCAneWhhdF9sb3dlcicsICd5aGF0X3VwcGVyJyldKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdChwcm9waGV0X3NhbGVzX3csIGZvcmVjYXN0X3NhbGVzX3cpDQpgYGANCg0KWW91IGNhbiB1c2UgdGhlIGBwcm9waGV0X3Bsb3RfY29tcG9uZW50c2AgZnVuY3Rpb24gdG8gc2VlIHRoZSBmb3JlY2FzdA0KYnJva2VuIGRvd24gaW50byB0cmVuZCwgd2Vla2x5IHNlYXNvbmFsaXR5LCBhbmQgeWVhcmx5IHNlYXNvbmFsaXR5Lg0KDQpgYGB7cn0NCnByb3BoZXRfcGxvdF9jb21wb25lbnRzKHByb3BoZXRfc2FsZXNfdywgZm9yZWNhc3Rfc2FsZXNfdykNCmBgYA0KDQpgYGB7cn0NCmR5cGxvdC5wcm9waGV0KHByb3BoZXRfc2FsZXNfdywgZm9yZWNhc3Rfc2FsZXNfdykNCmBgYA0KDQpgYGB7cn0NCiMgVXNlIHRoZSBvcmlnaW5hbCBkYXRhc2V0IHRvIGdldCBmaXR0ZWQgdmFsdWVzDQpmaXR0ZWRfdmFsdWVzX3cgPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX3csIGRmX3Byb3BoZXRfdykNCg0KIyBFeHRyYWN0IHRoZSBmaXR0ZWQgdmFsdWVzIChjb2x1bW4gJ3loYXQnIGNvbnRhaW5zIHRoZSBmaXR0ZWQgdmFsdWVzKQ0KZml0dGVkX3lfdyA8LSBmaXR0ZWRfdmFsdWVzX3ckeWhhdA0KDQojIEVuc3VyZSBhbGlnbm1lbnQgYmV0d2VlbiBhY3R1YWwgdmFsdWVzICh5KSBhbmQgZml0dGVkIHZhbHVlcyAoeWhhdCkNCmFjdHVhbF95X3cgPC0gZGZfcHJvcGhldF93JHkgICMgQWN0dWFsIHdlZWtseSBzYWxlcyB2YWx1ZXMNCg0KIyBDYWxjdWxhdGUgUk1TRSBmb3Igd2Vla2x5IGRhdGENCnJtc2VfcHJvcGhldF93IDwtIGNhbGN1bGF0ZV9ybXNlKG9ic2VydmVkID0gYWN0dWFsX3lfdywgcHJlZGljdGVkID0gZml0dGVkX3lfdykNCg0KIyBQcmludCBSTVNFDQpjYXQoIlJNU0UgZm9yIFByb3BoZXQgRml0dGVkIFZhbHVlcyAoV2Vla2x5KToiLCBybXNlX3Byb3BoZXRfdywgIlxuIikNCmBgYA0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIFJlc2lkdWFscw0KcmVzaWR1YWxzX3Byb3BoZXRfdyA8LSBhY3R1YWxfeV93IC0gZml0dGVkX3lfdyAgIyBSZXNpZHVhbHMgPSBBY3R1YWwgLSBGaXR0ZWQNCg0KIyBWaXN1YWxpemUgUmVzaWR1YWxzIHVzaW5nIHRzZGlzcGxheQ0KdHNkaXNwbGF5KHJlc2lkdWFsc19wcm9waGV0X3csIG1haW4gPSAiUmVzaWR1YWwgRGlhZ25vc3RpY3MgZm9yIFdlZWtseSBQcm9waGV0IE1vZGVsIikNCg0KIyBQZXJmb3JtIEFERiBUZXN0IGZvciBTdGF0aW9uYXJpdHkNCg0KYWRmX3Rlc3RfdyA8LSBhZGYudGVzdChyZXNpZHVhbHNfcHJvcGhldF93KQ0KY2F0KCJBREYgVGVzdCBwLXZhbHVlOiIsIGFkZl90ZXN0X3ckcC52YWx1ZSwgIlxuIikNCg0KaWYgKGFkZl90ZXN0X3ckcC52YWx1ZSA8IDAuMDUpIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIHN0YXRpb25hcnkgKHJlamVjdCBIMCkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIG5vdCBzdGF0aW9uYXJ5IChmYWlsIHRvIHJlamVjdCBIMCkuXG4iKQ0KfQ0KDQojIFBlcmZvcm0gU2VyaWFsIENvcnJlbGF0aW9uIFRlc3QNCmxqdW5nX2JveF90ZXN0X3cgPC0gQm94LnRlc3QocmVzaWR1YWxzX3Byb3BoZXRfdywgbGFnID0gMTAsIHR5cGUgPSAiTGp1bmctQm94IikNCmNhdCgiTGp1bmctQm94IFRlc3QgcC12YWx1ZToiLCBsanVuZ19ib3hfdGVzdF93JHAudmFsdWUsICJcbiIpDQoNCmlmIChsanVuZ19ib3hfdGVzdF93JHAudmFsdWUgPiAwLjA1KSB7DQogIGNhdCgiUmVzaWR1YWxzIHJlc2VtYmxlIHdoaXRlIG5vaXNlIChubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24pLlxuIikNCn0gZWxzZSB7DQogIGNhdCgiUmVzaWR1YWxzIHNob3cgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uLlxuIikNCn0NCg0KYGBgDQoNCiMjIyMgRGFpbHkgU2FsZXMNCg0KYGBge3J9DQpoZWFkKHNhbGVzX2RfdHMpDQoNCnBsb3Qoc2FsZXNfZF90cykNCmBgYA0KDQpgYGB7cn0NCnNhbGVzX2RfdmFsdWVzIDwtIGFzLm51bWVyaWMoc2FsZXNfZF90cykgICAjIEV4dHJhY3QgbnVtZXJpYyB2YWx1ZXMNCg0KZGZfcHJvcGhldF9kIDwtIGRhdGEuZnJhbWUoDQogIGRzID0gZGZfbWVyZ2VkX2QkZGF0ZSwgICMgRGF0ZXMNCiAgeSA9IHNhbGVzX2RfdmFsdWVzICAgIyBTYWxlcyB2YWx1ZXMNCikNCg0KYGBgDQoNCmBgYHtyfQ0KI1Byb3BoZXQgbW9kZWwNCg0KDQojcHJvcGhldF9zYWxlc19kIDwtIHByb3BoZXQoZGZfcHJvcGhldCwgd2Vla2x5LnNlYXNvbmFsaXR5ID0gVFJVRSkNCnByb3BoZXRfc2FsZXNfZCA8LSBwcm9waGV0KGRmX3Byb3BoZXRfZCkNCmBgYA0KDQpgYGB7cn0NCmZ1dHVyZV9zYWxlc19kIDwtIG1ha2VfZnV0dXJlX2RhdGFmcmFtZShwcm9waGV0X3NhbGVzX2QsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kcyA9IDYwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZXEgPSAnZGF5JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlX2hpc3RvcnkgPSBUKQ0KdGFpbChmdXR1cmVfc2FsZXNfZCkNCmBgYA0KDQpgYGB7cn0NCmZvcmVjYXN0X3NhbGVzX2QgPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX2QsIGZ1dHVyZV9zYWxlc19kKQ0KdGFpbChmb3JlY2FzdF9zYWxlc19kW2MoJ2RzJywgJ3loYXQnLCAneWhhdF9sb3dlcicsICd5aGF0X3VwcGVyJyldKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdChwcm9waGV0X3NhbGVzX2QsIGZvcmVjYXN0X3NhbGVzX2QpDQpgYGANCg0KYGBge3J9DQpwcm9waGV0X3Bsb3RfY29tcG9uZW50cyhwcm9waGV0X3NhbGVzX2QsIGZvcmVjYXN0X3NhbGVzX2QpDQpgYGANCg0KYGBge3J9DQpkeXBsb3QucHJvcGhldChwcm9waGV0X3NhbGVzX2QsIGZvcmVjYXN0X3NhbGVzX2QpDQpgYGANCg0KDQpgYGB7cn0NCiMgRXh0cmFjdCBmaXR0ZWQgdmFsdWVzIGZvciBSTVNFIGNhbGN1bGF0aW9uDQpmaXR0ZWRfdmFsdWVzX2QgPC0gcHJlZGljdChwcm9waGV0X3NhbGVzX2QsIGRmX3Byb3BoZXRfZCkNCg0KIyBFeHRyYWN0IGZpdHRlZCB2YWx1ZXMgKGNvbHVtbiAneWhhdCcpDQpmaXR0ZWRfeV9kIDwtIGZpdHRlZF92YWx1ZXNfZCR5aGF0DQphY3R1YWxfeV9kIDwtIGRmX3Byb3BoZXRfZCR5ICAjIEFjdHVhbCBzYWxlcyB2YWx1ZXMNCg0KIyBTdGVwIDg6IENhbGN1bGF0ZSBSTVNFDQpybXNlX3Byb3BoZXRfZCA8LSBjYWxjdWxhdGVfcm1zZShvYnNlcnZlZCA9IGFjdHVhbF95X2QsIHByZWRpY3RlZCA9IGZpdHRlZF95X2QpDQoNCiMgUHJpbnQgUk1TRQ0KY2F0KCJSTVNFIGZvciBQcm9waGV0IEZpdHRlZCBWYWx1ZXMgKERhaWx5KToiLCBybXNlX3Byb3BoZXRfZCwgIlxuIikNCmBgYA0KDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgUmVzaWR1YWxzDQpyZXNpZHVhbHNfcHJvcGhldF9kIDwtIGFjdHVhbF95X2QgLSBmaXR0ZWRfeV9kICAjIFJlc2lkdWFscyA9IEFjdHVhbCAtIEZpdHRlZA0KDQojIFZpc3VhbGl6ZSBSZXNpZHVhbHMgdXNpbmcgdHNkaXNwbGF5DQoNCnRzZGlzcGxheShyZXNpZHVhbHNfcHJvcGhldF9kLCBtYWluID0gIlJlc2lkdWFsIERpYWdub3N0aWNzIGZvciBEYWlseSBQcm9waGV0IE1vZGVsIikNCg0KIyBQZXJmb3JtIEFERiBUZXN0IGZvciBTdGF0aW9uYXJpdHkNCg0KYWRmX3Rlc3RfZCA8LSBhZGYudGVzdChyZXNpZHVhbHNfcHJvcGhldF9kKQ0KY2F0KCJBREYgVGVzdCBwLXZhbHVlOiIsIGFkZl90ZXN0X2QkcC52YWx1ZSwgIlxuIikNCg0KaWYgKGFkZl90ZXN0X2QkcC52YWx1ZSA8IDAuMDUpIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIHN0YXRpb25hcnkgKHJlamVjdCBIMCkuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJSZXNpZHVhbHMgYXJlIG5vdCBzdGF0aW9uYXJ5IChmYWlsIHRvIHJlamVjdCBIMCkuXG4iKQ0KfQ0KDQojIFBlcmZvcm0gU2VyaWFsIENvcnJlbGF0aW9uIFRlc3QNCmxqdW5nX2JveF90ZXN0X2QgPC0gQm94LnRlc3QocmVzaWR1YWxzX3Byb3BoZXRfZCwgbGFnID0gMjAsIHR5cGUgPSAiTGp1bmctQm94IikNCmNhdCgiTGp1bmctQm94IFRlc3QgcC12YWx1ZToiLCBsanVuZ19ib3hfdGVzdF9kJHAudmFsdWUsICJcbiIpDQoNCmlmIChsanVuZ19ib3hfdGVzdF9kJHAudmFsdWUgPiAwLjA1KSB7DQogIGNhdCgiUmVzaWR1YWxzIHJlc2VtYmxlIHdoaXRlIG5vaXNlIChubyBzaWduaWZpY2FudCBhdXRvY29ycmVsYXRpb24pLlxuIikNCn0gZWxzZSB7DQogIGNhdCgiUmVzaWR1YWxzIHNob3cgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uLlxuIikNCn0NCg0KYGBgDQoNCg0KDQpgYGB7cn0NCnJtc2VfbGlzdCA8LSBjKHJtc2Vfb2xzX20sIHJtc2Vfb2xzX3csIHJtc2Vfb2xzX2QsDQogICAgICAgICAgICAgICBybXNlX2JtX20sIHJtc2VfYm1fdywgcm1zZV9ibV9kLA0KICAgICAgICAgICAgICAgcm1zZV9nZ20xLCBybXNlX2dnbV93LCBybXNlX2dnbV9kLA0KICAgICAgICAgICAgICAgcm1zZV9odzIsDQogICAgICAgICAgICAgICBybXNlX2F1dG9fYXJpbWEsIHJtc2VfYXV0b19hcmltYV93LCBybXNlX2F1dG9fYXJpbWFfZCwNCiAgICAgICAgICAgICAgIHJtc2Vfc2FyaW1hX2QsDQogICAgICAgICAgICAgICBybXNlX3NhcmltYXhfZCwNCiAgICAgICAgICAgICAgIHJtc2VfZXhwX3NtX20sIHJtc2VfZXhwX3NtX3csIHJtc2VfZXhwX3NtX20sDQogICAgICAgICAgICAgICBybXNlX21peHR1cmVfbSwgcm1zZV9taXh0dXJlX3csIHJtc2VfbWl4dHVyZV9kLA0KICAgICAgICAgICAgICAgcm1zZV9wcm9waGV0X20sIHJtc2VfcHJvcGhldF93LCBybXNlX3Byb3BoZXRfZA0KICAgICAgICAgICAgICAgKQ0Kcm1zZV9saXN0DQpgYGANCiMjIEV2YWx1YXRpb24gb2YgYWxsIG1vZGVscw0KYGBge3J9DQojIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YSBmcmFtZSBmb3IgUk1TRSB2YWx1ZXMNCnJtc2VfdGFibGUgPC0gZGF0YS5mcmFtZSgNCiAgTW9kZWwgPSBjaGFyYWN0ZXIoKSwNCiAgTW9udGhseSA9IG51bWVyaWMoKSwNCiAgV2Vla2x5ID0gbnVtZXJpYygpLA0KICBEYWlseSA9IG51bWVyaWMoKSwNCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFDQopDQoNCiMgTW9udGhseSBSTVNFIHZhbHVlcw0Kcm1zZV9tb250aGx5IDwtIGMoDQogICJPTFMiID0gcm1zZV9vbHNfbSwNCiAgIkJhc3NfTW9kZWwiID0gcm1zZV9ibV9tLA0KICAiR0dNIiA9IHJtc2VfZ2dtMSwNCiAgIkhvbHRfV2ludGVycyIgPSBybXNlX2h3MiwNCiAgIkFyaW1hIiA9IHJtc2VfYXV0b19hcmltYSwNCiAgIkV4cF9TbW9vdGgiID0gcm1zZV9leHBfc21fbSwNCiAgIkdHTStTQVJJTUEiID0gcm1zZV9taXh0dXJlX20sDQogICJQcm9waGV0IiA9IHJtc2VfcHJvcGhldF9tDQopDQoNCiMgV2Vla2x5IFJNU0UgdmFsdWVzDQpybXNlX3dlZWtseSA8LSBjKA0KICAiT0xTIiA9IHJtc2Vfb2xzX3csDQogICJCYXNzX01vZGVsIiA9IHJtc2VfYm1fdywNCiAgIkdHTSIgPSBybXNlX2dnbV93LA0KICAiSG9sdF9XaW50ZXJzIiA9IE5hTiwNCiAgIkFyaW1hIiA9IHJtc2VfYXV0b19hcmltYV93LA0KICAiRXhwX1Ntb290aCIgPSBybXNlX2V4cF9zbV93LA0KICAiR0dNK1NBUklNQSIgPSBybXNlX21peHR1cmVfdywNCiAgIlByb3BoZXQiID0gcm1zZV9wcm9waGV0X3cNCikNCg0KIyBEYWlseSBSTVNFIHZhbHVlcw0Kcm1zZV9kYWlseSA8LSBjKA0KICAiT0xTIiA9IHJtc2Vfb2xzX2QsDQogICJCYXNzX01vZGVsIiA9IHJtc2VfYm1fZCwNCiAgIkdHTSIgPSBybXNlX2dnbV9kLA0KICAiSG9sdF9XaW50ZXJzIiA9IE5hTiwNCiAgIkFyaW1hIiA9IHJtc2VfYXV0b19hcmltYV9kLA0KICAiRXhwX1Ntb290aCIgPSBybXNlX2V4cF9zbV9kLA0KICAiR0dNK1NBUklNQSIgPSBybXNlX21peHR1cmVfZCwNCiAgIlByb3BoZXQiID0gcm1zZV9wcm9waGV0X2QNCikNCg0KIyBDb21iaW5lIFJNU0UgdmFsdWVzIGludG8gYSB0YWJsZQ0KZm9yIChtb2RlbF9uYW1lIGluIG5hbWVzKHJtc2VfbW9udGhseSkpIHsNCiAgcm1zZV90YWJsZSA8LSByYmluZChybXNlX3RhYmxlLCBkYXRhLmZyYW1lKA0KICAgIE1vZGVsID0gbW9kZWxfbmFtZSwNCiAgICBNb250aGx5ID0gcm1zZV9tb250aGx5W21vZGVsX25hbWVdLA0KICAgIFdlZWtseSA9IHJtc2Vfd2Vla2x5W21vZGVsX25hbWVdLA0KICAgIERhaWx5ID0gcm1zZV9kYWlseVttb2RlbF9uYW1lXQ0KICApKQ0KfQ0KDQojIFZpZXcgdGhlIFJNU0UgdGFibGUNCnByaW50KHJtc2VfdGFibGUpDQoNCmBgYA0KDQpCZXN0IG1vZGVscyBhcmU6DQoNCiogTW9udGhseTogR0dNICsgU0FSSU1BDQoqIFdlZWtseTogR0dNICsgU0FSSU1BDQoqIERhaWx5OiBQcm9waGV0DQoNCiMjIEV2YWx1YXRpb24gb2YgYmVzdCBtb2RlbHMgb24gVGVzdCBTZXQNCiMjIyBJbXBvcnQgdGVzdCBzZXQNCmBgYHtyfQ0KIyB0YXJnZXQgdmFyaWFibGUNCnRlc3Rfc2FsZXNfZGYgPC0gcmVhZF9leGNlbCgiZGF0YS9zYWxlcy90ZXN0X2RhdGEueGxzeCIpDQpoZWFkKHRlc3Rfc2FsZXNfZGYpDQpgYGANCmBgYHtyfQ0KZGZfc2FsZXNfbV90ZXN0IDwtIHRlc3Rfc2FsZXNfZGYgJT4lDQogIG11dGF0ZShtb250aCA9IGZsb29yX2RhdGUoZGF0ZSwgIm1vbnRoIikpICU+JSAjIEV4dHJhY3QgbW9udGgNCiAgZ3JvdXBfYnkobW9udGgpICU+JQ0KICBzdW1tYXJpc2Uoc2FsZXNfbSA9IHN1bShzYWxlc19jb3ApLCBiYXJfbSA9IHN1bShiYXIpLCBmb29kX20gPSBzdW0oZm9vZCkNCiAgICAgICAgICAgICkgICAgICMgU3VtbWluZyB2YWx1ZXMNCg0KaGVhZChkZl9zYWxlc19tX3Rlc3QpDQpgYGANCmBgYHtyfQ0KIyMgc2FsZXMgd2Vla2x5DQpkZl9zYWxlc193X3Rlc3QgPC0gdGVzdF9zYWxlc19kZiAlPiUNCiAgbXV0YXRlKHdlZWsgPSBmbG9vcl9kYXRlKGRhdGUsICJ3ZWVrIikpICU+JSAjIEV4dHJhY3QgbW9udGgNCiAgZ3JvdXBfYnkod2VlaykgJT4lDQogIHN1bW1hcmlzZShzYWxlc193ID0gc3VtKHNhbGVzX2NvcCksIGJhcl93ID0gc3VtKGJhciksIGZvb2RfdyA9IHN1bShmb29kKSkgICAgICMgU3VtbWluZyB2YWx1ZXMNCg0KaGVhZChkZl9zYWxlc193X3Rlc3QpDQpgYGANCiMjIEZvcmVjYXN0IHZzIEFjdHVhbA0KIyMjIE1vbnRseQ0KYGBge3J9DQpgYGANCmBgYHtyfQ0KY3Vtc3VtKHNhbGVzX21fdHMpDQpmb3JlY2FzdF9jdW11bGF0aXZlDQpgYGANCg0KIyMjIFdlZWtseQ0KIyMjIERhaWx5DQoNCiMjIEZvcmVjYXN0IHdpdGggQmVzdCBNb2RlbHMNCiMjIyBNb250bHkNCiMjIyBXZWVrbHkNCiMjIyBEYWlseQ0K